为什么具有默认参数的Kotlin函数创建了一个没有使用参数的方法

在Kotlin中查看这个示例代码:

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

反编译成Java代码(工具 – > Kotlin – >显示Kotlin字节码 – >反编译),我得到了下面的代码

 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); } 

我注意到由此产生的Java方法有一个未使用的Object var3参数。

我认为它可能与类中的函数有关,但反编译此代码

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

我得到了这个代码

 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); } } 

正如你所看到的, Object参数还没有被使用,只是坐在那里。 额外的测试,我注意到扩展方法相同的行为。 当默认参数是最后一个(即fun foo(bar: Int, baz: Int = 0) {}

我也做了一个基本的测试,检查使用下面的代码调用该函数时设置的值是多少

 fun main(args: Array<String>) { foo(baz = 2) } 

 class Something { init { foo(baz = 2) } } 

反编译后,我得到了下面的代码

 public static final void main(@NotNull String[] args) { Intrinsics.checkParameterIsNotNull(args, "args"); foo$default(0, 2, 1, (Object)null); } 

 public final class Something { public Something() { FooKt.foo$default(0, 2, 1, (Object)null); } } 

这使得甚至没有什么意义。

我的问题是:为什么Kotlin为默认参数的函数生成一个未使用的参数? 这是一个错误?

据此,目前尚未使用,但保留用于稍后添加具有默认值的超级呼叫。

你可以在这里看到它的行动:

 open class Foo { open fun foo(bar: Int = 0, baz: Int) { /* ... */ } } class Blah: Foo() { override fun foo(bar: Int, baz: Int) { } } 

这将生成一个字节码到Java的Foo

 public class Foo { public 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(var4 != null) { throw new UnsupportedOperationException("Super calls with default arguments not supported in this target, function: foo"); } else { if((var3 & 1) != 0) { var1 = 0; } var0.foo(var1, var2); } } }