How Default argument and @JvmOverloads work on Kotlin?

3.8k views Asked by At

When we created fun with Kotlin like this

fun foo(bar: Int = 0, baz: Int) { /* ... */ }

foo(baz = 1) // The default value bar = 0 is used

So in java we need to write it this way E.g.

don't need to write

void foo(int bar, int baz){
...
}

void foo(int baz){
foo(0,baz);
}

Let's imagine if we have 10+ params. I wonder how Kotlin handle this. Will Kotlin generate all possible methods? Or it just generate the method that programmer really use?

3

There are 3 answers

0
hotkey On BEST ANSWER

There won't be 2^N overloads generated. As said in the docs,

For every parameter with a default value, this will generate one additional overload, which has this parameter and all parameters to the right of it in the parameter list removed.

For a function with default parameters, say,

 fun foo(bar: Int = 1, baz: Int = 2, qux: Int = 3) { /*...*/ }

it will generate overloads

 foo()
 foo(bar)
 foo(bar, baz)
 foo(bar, baz, qux)
0
Rafal G. On

From the documentation:

Instructs the Kotlin compiler to generate overloads for this function that substitute default parameter values.

If a method has N parameters and M of which have default values, M overloads are generated: the first one takes N-1 parameters (all but the last one that takes a default value), the second takes N-2 parameters, and so on.

0
Mibac On

When you have a function with default parameters Kotlin generates a synthetic function with the parameters as required and a additional Int as the last parameters and does some bit manipulation

Example Kotlin function:

fun lotsOfParameters(a: String = "Default",
                     b: Byte = 2,
                     c: Char = 'p',
                     d: Boolean = false,
                     e: Any = true,
                     f: Int = 2) {
}

Compiled Java code:

public static final void lotsOfParameters(@NotNull String a, byte b, char c, boolean d, @NotNull Object e, int f) {
  Intrinsics.checkParameterIsNotNull(a, "a");
  Intrinsics.checkParameterIsNotNull(e, "e");
}

// $FF: synthetic method
// $FF: bridge method
public static void lotsOfParameters$default(String var0, byte var1, char var2, boolean var3, Object var4, int var5, int var6, Object var7) {
  if ((var6 & 1) != 0) {
     var0 = "Default";
  }

  if ((var6 & 2) != 0) {
     var1 = 2;
  }

  if ((var6 & 4) != 0) {
     var2 = 'p';
  }

  if ((var6 & 8) != 0) {
     var3 = false;
  }

  if ((var6 & 16) != 0) {
     var4 = true;
  }

  if ((var6 & 32) != 0) {
     var5 = 2;
  }

  lotsOfParameters(var0, var1, var2, var3, var4, var5);
}