[英]Kotlin method overloading
以下聲明在Kotlin中是合法的。
fun foo(): String = "foo_1"
fun <T> foo(): T = "foo_2" as T
作為字節碼我們得到:
public final static foo()Ljava/lang/String;
// signature <T:Ljava/lang/Object;>()TT;
// declaration: T foo<T>()
public final static foo()Ljava/lang/Object;
也可以從Kotlin調用這兩種方法。
當我試圖從Java中調用其中任何一個時,問題出現了:
ClassKt.foo()
曖昧的電話。 兩種方法都匹配......
如何避免這樣的問題? 如何處理這樣的方法? 如果第三方kt庫有同樣的問題怎么辦?
上面的例子是合成的例子。
為什么它與Kotlin一起開始...在Java中有兩種方法,如:
private static String test() {
return "";
}
private static <T> T test() {
return null;
}
會導致編譯時錯誤。 對於java devs來說,這很明顯,這些方法將具有相同類型的擦除。 但這是由javac
強加的規則, 而不是由運行此代碼的JVM
強加的規則。 因此, javac
不會將兩個方法視為僅具有不同的返回類型作為重載。 好吧, kotlin
是一種不同的語言,因為它在JVM
上運行(期望有效的字節碼),它允許處理只有返回類型不同的方法作為重載。 我還沒看看字節碼並理解它是如何發生的; 似乎這只適用於通用代碼,因此在kotlin的情況下類型擦除可能略有不同。
現在,為什么從java調用這樣的方法失敗的事情應該是顯而易見的。 Kotlin為此提供了一個簡潔的解決方案: @JvmName("someDistinctName")
。 我不完全確定它是如何工作的......但是,盡管我認為這將創建一個橋接方法。
編輯
@JvmName
將在字節碼級別重命名該方法。
從java調用代碼時,可以使用@JvmName來區分代碼:
@JvmName("fooString")
fun foo(): String = "foo_1"
fun <T> foo(): T = "foo_2" as T
這將允許使用ClassKt.fooString()
調用Java中的String方法,該方法可以解決沖突。
一個簡單的解決方案是在Kotlin中編寫一個幫助方法,然后調用它。
另一種只使用Java的方法是為兩種方法獲取MethodHandle
並使用它們:
MethodHandle MH_fooString = lookup().findStatic(ClassKt.class, "foo", methodType(String.class));
MethodHandle MH_fooT = lookup().findStatic(ClassKt.class, "foo", methodType(Object.class));
String foo = (String) MH_fooString.invokeExact();
它不是那么簡單,但需要處理異常。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.