Why can't you use named arguments when calling Java methods from Kotlin, and how does this interact with varargs?
answer
- Java bytecode drops parameter names by default
- named args forbidden when callee is Java
- -parameters doesn't enable Kotlin named calls
- spread * to pass array into a vararg
- can't name a Java vararg argument
basics
~10 sJava bytecode usually doesn't keep parameter names, so Kotlin can't reliably match a name to a Java method's parameter. Therefore Kotlin forbids named arguments on calls to Java methods; you must pass them positionally.
solid answer
~40 sNamed arguments rely on parameter names being part of the API. Java .class files don't retain parameter names unless compiled with -parameters, and even then Kotlin does not honor them for named-argument calls — so Kotlin disallows the name = value syntax when the callee is a Java method. You call Java methods positionally. This also affects varargs: when passing values to a Java vararg from Kotlin you use the spread operator (*) on an array, and you cannot name a Java vararg argument. The rule is a deliberate safety measure: relying on names that may be absent or compiler-dependent would make calls fragile. For Kotlin-declared functions, names are always available from metadata, so named arguments work fully.
code
kotlin · 5 lines// Java: void configure(int width, int height, String... tags)
val tags = arrayOf("a", "b")
configure(800, 600, *tags) // positional + spread: OK
// configure(width = 800, height = 600, *tags) // ERROR: named args not allowed for Java methodsgo deeper
Knows Java methods are called positionally and that named args don't work there.
Explains it's because Java bytecode lacks parameter names by default, and uses spread for varargs.
Adds that -parameters still doesn't enable named calls, and explains the named-vararg-needs-single-spread nuance.
Articulates the API-stability rationale for keeping names a Kotlin-only contract and the cross-language design tradeoff.
## Where parameter names live Named arguments bind a value to a parameter **by name**, so the name must be a dependable part of the callee's API. - For **Kotlin** functions, parameter names are stored in Kotlin metadata and are always available to the compiler — named arguments work everywhere. - For **Java** methods, parameter names are **not retained in bytecode by default**. They appear only if the class was compiled with the `javac -parameters` flag, and historically tooling couldn't rely on this. Because the name may be missing or unreliable, Kotlin makes a clean rule: **you cannot use named-argument syntax when calling a Java method.** You must pass arguments positionally. ```kotlin // Java: void setColor(int red, int green, int blue) // Kotlin call: obj.setColor(255, 0, 0) // OK, positional // obj.setColor(red = 255, ...) // ERROR: named args not allowed for Java methods ``` ## Interaction with varargs Java varargs add a related limitation: - To pass an existing array to a Java (or Kotlin) **vararg** parameter, Kotlin uses the **spread operator** `*`: ```kotlin val names = arrayOf("a", "b") javaObject.printAll(*names) // spread into a Java String... param ``` - You **cannot name** a Java vararg argument, consistent with the no-named-args-for-Java rule. - Even for **Kotlin** functions, a vararg parameter passed by name must receive a **single spread array** (`vararg = *arr`), not a comma-separated list — naming and the multi-value vararg syntax don't combine. ## Why this is the right tradeoff Allowing named arguments against possibly-absent Java parameter names would make code compile or break depending on how a dependency was built. Kotlin prefers a predictable boundary: names are a first-class part of **Kotlin** signatures only. ## Quick checklist - Calling a Java method? Positional only; no `name = value`. - Passing an array to any vararg? Use `*array`. - Naming a Kotlin vararg? Pass exactly one spread array.
- Does compiling the Java code with -parameters enable Kotlin named-argument calls?No. Even when names are present in bytecode, Kotlin still disallows named arguments for Java methods, keeping the boundary predictable.
- How do you pass an existing array into a vararg parameter?Use the spread operator: f(*array). Without it you'd be passing the array itself as a single element.
saying these in an interview costs you the question
- Saying named arguments work for Java methods if you import them right
- Believing -parameters re-enables named calls in Kotlin
- Confusing spread (*array) with simply passing the array
- Claiming you can name a Kotlin vararg with a comma-separated list of values