+ 我要发布
我发布的 我的标签 发现
浏览器扩展
斑点象@Edge

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 限制的作用。有趣吧~
你可能想看的