Android 運用@JvmName解決函數簽名沖突問題詳解
Kotlin(JVM) 中定義下面這樣兩個方函數時,編譯器會報錯
fun foo(value: List<String>) {} fun foo(value: List<Int>) {}
Platform declaration clash: The following declarations have the same JVM signature (method(Ljava/util/List;)V):
因為 Java 的泛型編譯期擦除,所以 JVM 無法識別簽名中泛型的區別,認為這兩個函數簽名沖突瞭
此時有一個小技巧是使用 @JvmName
規避這種沖突
@JvmName("fooB") fun foo(value: List<String>) {} @JvmName("fooA") fun foo(value: List<Int>) {}
@JvmName
會制定一個針對 JVM 的名字, 當我們分別指定瞭不同名字後, JVM 認為這是兩個不同的函數,就不會報錯瞭
反編譯成 Java 代碼,相當於下面這樣
//Test.kt 是文件名 public final class TestKt { public static final void fooB(List<String> value) {} public static final void fooA(List<Integer> value) {} }
需要註意,這在 interface 中使用可能有限制
interface Test { @JvmName("fooB") fun foo(value: List<String>) { } @JvmName("fooA") fun foo(value: List<Int>) { } }
編譯器報錯如下:
@JvmName annotation is not applicable to this declaration
此時可以如下進行規避
interface Test { @Suppress("INAPPLICABLE_JVM_NAME") @JvmName("fooB") fun foo(value: List<String>) { } @Suppress("INAPPLICABLE_JVM_NAME") @JvmName("fooA") fun foo(value: List<Int>) { } }
@JvmName 本來是為瞭 Java 與 Kotlin 互操作性而生的註解,但是在 Kotlin 側單獨使用,也可以起到規避一些 JVM 限制的作用。有趣吧~
到此這篇關於Android 運用@JvmName解決函數簽名沖突問題詳解的文章就介紹到這瞭,更多相關Android @JvmName內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!