为什么具有默认参数的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); } } }