In Kotlin, the following code compiles:
class Foo {
fun bar(foo: List<String>): String {
return ""
}
fun bar(foo: List<Int>): Int {
return 2;
}
}
This code, however, does not:
class Foo {
fun bar(foo: List<String>): String {
return ""
}
fun bar(foo: List<Int>): String {
return "2";
}
}
Compiling this will cause the following error:
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
In Java, neither example will compile:
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";
}
}
Unsurprisingly, both of the prior snippets generate the familiar compiler error:
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
What surprises me is that the first Kotlin example works at all, and second, if it works, why does the second Kotlin example fail? Does Kotlin consider a method's return type as part of its signature? Furthermore, why do method signatures in Kotlin respect the full parameter type, in contrast with Java?