【发布时间】:2017-09-03 15:06:29
【问题描述】:
在 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 会为具有默认参数的函数生成未使用的参数?它是一个错误吗?
【问题讨论】:
-
当您的默认参数是最后一个时,您会得到什么?如
fun foo(bar: Int, baz: Int = 0) {} -
@Les 刚刚检查过。是一样的(即生成了奇怪的 Object var)
-
有没有试过调用,看看java代码中传入的对象是什么?
-
@DPM 我刚刚做了一个基本测试(
foo(baz = 2)),传递的参数是null。我也编辑了问题 -
如果您只是出于好奇而问这个问题,最好在 Kotlin 论坛或 Slack 中提问。如果你想从 Java 调用一个带有默认参数的 Kotlin 函数,你应该用
@JvmOverloads注解来注解它,这样编译器就会生成干净的重载方法,没有魔法参数。
标签: kotlin