试图弄清楚为什么这在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允许这样做,或者为什么它至少不是警告,因为如果不是编译器,开发人员会感到很困惑。事后看来,我不应该以这种方式定义班级,但是在这种情况下,警告会很有帮助。
答案 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);
}
}
编译器没有生成用于歧义检查的其他方法,现在完全由程序员来调用哪个方法。