15
在科特林,下面的代碼編譯:刪除在Kotlin中如何工作?
class Foo {
fun bar(foo: List<String>): String {
return ""
}
fun bar(foo: List<Int>): Int {
return 2;
}
}
此代碼,但並不:
class Foo {
fun bar(foo: List<String>): String {
return ""
}
fun bar(foo: List<Int>): String {
return "2";
}
}
編譯,這將導致以下錯誤:
Error:(8, 5) Kotlin: Platform declaration clash: The following declarations have the same JVM signature (foo(Ljava/util/List;)Ljava/lang/String;):
fun foo(layout: List<Int>): String
fun foo(layout: List<String>): String
在Java中,這兩個例子都不會編譯:
class Foo {
String bar(List<Integer> foo) {
return "";
}
Integer bar(List<String> foo) {
return 2;
}
}
class Foo {
String bar(List<Integer> foo) {
return "";
}
String bar(List<String> foo) {
return "2";
}
}
不出所料,無論是之前片段的產生熟悉的編譯器錯誤:
Error:(13, 12) java: name clash: bar(java.util.List<java.lang.String>) and bar(java.util.List<java.lang.Integer>) have the same erasure
讓我驚訝的是,第科特林例如在所有工作,和第二,如果它的工作原理,爲什麼第二科特林例子失敗? Kotlin是否將方法的返回類型視爲其簽名的一部分?此外,爲什麼Kotlin中的方法簽名要尊重完整的參數類型,與Java相比?
但是爲什麼第一個Kotlin示例在沒有這個註解的情況下編譯? JVM是否可以識別具有不同返回類型的方法?根據[這個答案](http://stackoverflow.com/a/16149445/1772342),返回類型不是方法簽名的一部分。 – breandan
啊,我明白了。也許Java在編譯期間不允許具有不同返回類型的相同名稱/參數方法,但JVM能夠識別它們? – breandan
@breandan好的,返回類型是簽名的一部分,但在第一種情況下,兩種方法是不同的(即使參數擦除類型相同),因此簽名是不同的。它們分別是'foo(Ljava/util/List;)Ljava/lang/String;'和'foo(Ljava/util/List;)Ljava/lang/Integer;'。 Java只考慮名稱衝突檢查中的參數類型和方法名稱,所以Java中的第一個示例不會編譯。這更多的是關於重載和非類型擦除,並且可以很容易地用語言修復(如Kotlin所做的那樣) – Strelok