skip to content

Given fun box(w: Int, h: Int = 1, color: String = "red", filled: Boolean = true) annotated with @JvmOverloads, which exact method signatures become visible to Java?

level: middleimportance: must knowfreq 55%

answer

  1. Drop defaults right-to-left only
  2. Overloads = (#defaulted params) + 1
  3. Mandatory params form the prefix
  4. No arbitrary-subset overloads
  5. Shorter ones forward to the full method

basics

~10 s

Java sees one method per trailing-defaults combination: box(w), box(w,h), box(w,h,color), and box(w,h,color,filled). Three parameters have defaults, so four overloads total, each dropping defaults from the right.

solid answer

~30 s

There are three parameters with defaults (h, color, filled), so @JvmOverloads emits the full-arity method plus three reduced ones, removing defaults right-to-left: box(int) — uses h=1, color=\"red\", filled=true; box(int,int) — color=\"red\", filled=true; box(int,int,String) — filled=true; box(int,int,String,boolean) — the full method. That's N+1 = 4 overloads. There is NO overload that, say, supplies filled while omitting color, because defaults can only be dropped from the rightmost end. The reduced overloads are real JVM methods that delegate to the full one, passing the default values. Kotlin still sees the single function.

code

kotlin · 7 lines
kotlin
@JvmOverloads
fun box(w: Int, h: Int = 1, color: String = "red", filled: Boolean = true) {}
// Java sees:
// box(int)
// box(int,int)
// box(int,int,String)
// box(int,int,String,boolean)

go deeper

for a junior

Recognizes extra overloads appear but may miscount them.

for a middle

Correctly enumerates the N+1 overloads and the right-to-left rule.

for a senior

Explains the delegation/forwarding and why arbitrary subsets aren't possible.

for a principal

Discusses how this constrains API evolution and when explicit overloads or builders are preferable.

## The rule @JvmOverloads removes parameters that have defaults, **starting from the rightmost defaulted parameter and moving left**, generating one overload at each step plus the original full-arity method. It never produces overloads for arbitrary subsets of parameters. ```kotlin @JvmOverloads fun box( w: Int, // no default — always present h: Int = 1, color: String = "red", filled: Boolean = true, ) ``` ## Generated Java-visible overloads Three parameters carry defaults (`h`, `color`, `filled`), so **N+1 = 4** methods: - `box(int w)` → calls full with `h=1, color="red", filled=true` - `box(int w, int h)` → calls full with `color="red", filled=true` - `box(int w, int h, String color)` → calls full with `filled=true` - `box(int w, int h, String color, boolean filled)` → the original ## Why no `box(w, filled)` overload Defaults are stripped **only contiguously from the right**. You cannot omit `color` while keeping `filled`, because that would require positional reordering the JVM can't infer. If you genuinely need that, declare explicit overloads or use named arguments from Kotlin. ## The `w` parameter Because `w` has **no default**, every generated overload keeps it — it forms the mandatory prefix. ## Counting trick Overloads generated = (number of parameters that have defaults) + 1. Here 3 + 1 = 4. If only `filled` had a default, you'd get 2 overloads. ## Delegation Each shorter overload is a thin synthetic method that fills in the omitted defaults and forwards to the maximal-arity implementation — there is no code duplication of the body.

  • How many overloads if only the last two parameters had defaults?
    Three: the full method plus one dropping the last default and one dropping both — (2 defaults) + 1.
  • Can Java call box(w, filled=true) skipping color and h?
    No. Defaults can only be dropped contiguously from the right, so there's no such overload; you'd need an explicit overload.

saying these in an interview costs you the question

  • Counting 2^N overloads for every subset
  • Claiming you can skip a middle defaulted parameter
  • Forgetting the mandatory leading parameter is always present
  • Saying it duplicates the function body in each overload

context