Kotlin类中的“重复”方法

时间:2019-07-25 19:40:52

标签: kotlin

试图弄清楚为什么这在Kotlin中至少不是警告

我有一堂课,使用了与此类似的方法,后来又让我伤了:

class TestDuplicates {
    fun doSomething() {
        print("doSomething()")
    }
    fun doSomething(optional: String = "") {        
        print("doSomething($optional)")
    }
}

fun main() {    
    // Which is called? Why not at least warning?
    TestDuplicates().doSomething()
}

为什么Kotlin允许这样做,或者为什么它至少不是警告,因为如果不是编译器,开发人员会感到很困惑。事后看来,我不应该以这种方式定义班级,但是在这种情况下,警告会很有帮助。

1 个答案:

答案 0 :(得分:3)

如果我们将其反编译为Java字节码,这就是我们得到的:

public final class TestDuplicates {
public final void doSomething(@NotNull String optional) {
  Intrinsics.checkParameterIsNotNull(optional, "optional");
  String var2 = "doSomething(" + optional + ")";
  System.out.print(var2);
}

// $FF: synthetic method

public static void doSomething$default(TestDuplicates var0, String var1, int var2,  Object var3) {
  if ((var2 & 1) != 0) {
     var1 = "";
  }
  var0.doSomething(var1);
}

public final void doSomething() {
  String var1 = "doSomething()";
  System.out.print(var1);
 }
}

显然,编译器会生成一个综合方法,在该方法中,如果您选择的方法提供了非默认值,则它将检查条件,否则,它将调用var1 = "doSomething()";,这是您的方法,没有默认参数。

为什么没有警告?这是因为您知道您要输入的内容,并且编译器对此很满意,因为它知道要满足的基本条件。

反编译主程序

 public final class MainKt {
 public static final void main() {
   (new TestDuplicates()).doSomething();
}

 // $FF: synthetic method
 public static void main(String[] var0) {
   main();
 }
}

为解决名称不明确的问题,编译器生成了一种综合方法来进行其他检查。如果删除默认值然后再次反编译,则可以证明该语句。

class TestDuplicates {

 fun doSomething() {
    print("doSomething()")
 }

 fun doSomething(optional: String) { //Removed default value
    print("doSomething($optional)")
 }
}

反编译后:

public final class TestDuplicates {

 public final void doSomething() {
  String var1 = "doSomething()";
  boolean var2 = false;
  System.out.print(var1);
}

 public final void doSomething(@NotNull String optional) {
  Intrinsics.checkParameterIsNotNull(optional, "optional");
  String var2 = "doSomething(" + optional + ')';
  boolean var3 = false;
  System.out.print(var2);
 }
}

编译器没有生成用于歧义检查的其他方法,现在完全由程序员来调用哪个方法。