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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

fundroid

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值