巧用 @JvmName 解决 Kotlin 函数签名冲突

Posted fundroid_方卓

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了巧用 @JvmName 解决 Kotlin 函数签名冲突相关的知识,希望对你有一定的参考价值。

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 限制的作用。有趣吧~

以上是关于巧用 @JvmName 解决 Kotlin 函数签名冲突的主要内容,如果未能解决你的问题,请参考以下文章

KotlinKotlin 与 Java 互操作 ① ( 变量可空性 | Kotlin 类型映射 | Kotlin 访问私有属性 | Java 调用 Kotlin 函数 )

巧用Kotlin反射实现按值取名,调试做到多快好省

巧用Kotlin反射实现按值取名,调试做到多快好省

巧用Kotlin反射实现按值取名,调试做到多快好省

Kotlin常⽤注解

Kotlin 初学者Java和Kotlin互操作