Solved
See this example code in Kotlin:
fun foo(bar: Int = 0, baz: Int) {
/* ... */
}
After decompiling it to Java code (Tools → Kotlin → Show Kotlin Bytecode → Decompile) I got the following code
public static final void foo(int bar, int baz) {
}
// $FF: synthetic method
// $FF: bridge method
public static void foo$default(int var0, int var1, int var2, Object var3) {
if ((var2 & 1) != 0) {
var0 = 0;
}
foo(var0, var1);
}
I noticed that the resulting Java method has an unused Object var3
parameter.
I kind of thought that it may be related to functions in a class but when decompiling this code
class Foo {
fun foo(bar: Int = 0, baz: Int) {
/* ... */
}
}
I got this code
public final class Foo {
public final void foo(int bar, int baz) {
}
// $FF: synthetic method
// $FF: bridge method
public static void foo$default(Foo var0, int var1, int var2, int var3, Object var4) {
if ((var3 & 1) != 0) {
var1 = 0;
}
var0.foo(var1, var2);
}
}
As you can see the Object parameter is still unused and just sits there. Upon additional tests I noticed the same behavior for extension methods. The same goes when the default parameter is last (i.e. fun foo(bar: Int, baz: Int = 0) {}
)
I’ve also done a basic test to check what is that value set to when calling that function using the code below
fun main(args: Array<String>) {
foo(baz = 2)
}
And
class Something {
init {
foo(baz = 2)
}
}
After decompiling it I got the following code
public static final void main(@NotNull String[] args) {
Intrinsics.checkParameterIsNotNull(args, "args");
foo$default(0, 2, 1, (Object)null);
}
And
public final class Something {
public Something() {
FooKt.foo$default(0, 2, 1, (Object)null);
}
}
Which makes even less sense whatsoever.
My question is: Why does Kotlin generate an unused parameter for functions with default parameters? Is it a bug?