簡體   English   中英

Kotlin方法重載

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM