2017-03-21 14 views
15

KOTLIN, aşağıdaki kodu derler:Silinme Kotlin'de nasıl çalışır?

class Foo { 
    fun bar(foo: List<String>): String { 
     return "" 
    } 

    fun bar(foo: List<Int>): Int { 
     return 2; 
    } 
} 

Bu kod, ancak, yapmaz: Aşağıdaki hataya neden olur, bu Derleme

class Foo { 
    fun bar(foo: List<String>): String { 
     return "" 
    } 

    fun bar(foo: List<Int>): String { 
     return "2"; 
    } 
} 

: Java'da

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 

, her iki örnek de derlenmez:

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"; 
    } 
} 
Beni şaşırtan eğer çalışırsa ilk Kotlin örneği, ikinci hiç ve çalışmasıdır

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 

, neden ikinci Kotlin örneği başarısız oluyor:

Beklenildiği gibi önceki snippet'lerin hem tanıdık derleyici hatası oluşturur ? Kotlin imzasının bir parçası olarak bir yöntemin dönüş türünü düşünüyor mu? Dahası, Kotlin'deki yöntem imzaları, Java'nın aksine, tam parametre türüne niçin uymaktadır?

cevap

13

Aslında Kotlin, örneğinizdeki iki yöntem arasındaki farkı bilir, ancak jvm bunu yapmayacaktır. Bu yüzden bir "platform" çatışması.

Sen ikinci örnek @JvmName ek açıklama kullanarak derleme yapabilirsiniz:

class Foo { 
    @JvmName("barString") fun bar(foo: List<String>): String { 
    return "" 
    } 

    @JvmName("barInt") fun bar(foo: List<Int>): String { 
    return "2"; 
    } 
} 

Bu açıklama bu çok nedeni var. interop documentation'da daha fazlasını okuyabilirsiniz.

+0

Ama sonra ilk Kotlin örneği bu açıklama olmadan neden derleniyor? JVM farklı dönüş türlerine sahip yöntemleri tanır mı? [Bu cevap] 'a göre (http://stackoverflow.com/a/16149445/1772342), dönüş türü bir yöntemin imzasının bir parçası değildir. – breandan

+0

Ah, anlıyorum. Belki de Java, derleme sırasında farklı dönüş türleriyle aynı isim/parametre yöntemlerine izin vermez, ancak JVM bunları tanır mı? – breandan

+4

@breandan iyi evet, dönüş tipi imzanın bir parçasıdır, ancak ilk durumda iki yöntem için farklıdır (her ne kadar parametre silinen tip aynı olsa da), bu yüzden imzalar farklıdır. Onlar sırasıyla (Ljava/util/List;) Ljava/lang/String; 've' foo (Ljava/util/List;) Ljava/lang/Integer; '' dır. Java, yalnızca ilk olarak Java'daki örneklerin derlenmemesi için parametre türlerini ve yöntem adlarını çarpışma denetiminde dikkate alır. Bu, aşırı yüklenme ve anot tipi silme hakkında daha fazladır ve kolaylıkla (Kotlin'in yaptığı gibi) dilde sabitlenebilmektedir – Strelok