为什么使用默认参数的Kotlin函数会创建一个未使用参数

时间:2017-09-03 15:06:29

标签: 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参数仍未使用,只是坐在那里。 在进行其他测试后,我注意到扩展方法的行为相同。默认参数为last(即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为默认参数的函数生成一个未使用的参数?这是一个错误吗?

1 个答案:

答案 0 :(得分:7)

根据this,目前它尚未使用,但保留用于稍后添加默认值的超级调用。

你可以在这里看到它:

Foo

将生成一个字节码到Java 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); } } }

{{1}}