kotlin与java互操作中的冲突

2021-07-09


以下基于kotlin 1.5.20 版本

1. kotlin中的属性与方法

在kotlin中的公共属性默认会被编译成为相应的gettersetter方法在java中可以去被调用。

在编译后的JVM字节码中,公共属性被编译成指定的gettersetter签名的方法,所以在java中使用该属性是通过方法的方式进行使用的,而不是字段。

//在java中将被编译成getName()与setName(String)的方法签名
var name:String=""

1.1. JVM签名冲突

由于kotlin编译时会有这样的机制,所以以下代码就会出现问题。

interface IStudent{
   
    //定义了一个只读属性name
    val name:String

    //定义了一个getName的方法
    //此处会报错
    fun getName():String
}

此处会报错 Platform declaration clash: The following declarations have the same JVM signature (getName()Ljava/lang/String;)

由于只读属性name最终会被编译成String getName()这样的方法签名,所以实际上与下面定义的方法已经产生了签名冲突了。

val name:String -> 编译成:String getName()
 fun getName():String -> 编译成:String getName()
//这里编译后已经存在相同签名的方法了

对于这样的情况,意味着有以下限制:

  1. 在kotlin中,同一个类/接口使用了只读属性(val)则不能定义相应的getter方法;使用了可读写属性(var)则不能定义相应的gettersetter方法
  2. 在kotlin中,子类继承的父类/接口也不能出现冲突的属性或方法
  3. 同理在java与kotlin混合使用的互操作情况下,不管在java中继承kotlin的类/接口,还是反过来,都双方都不允许出现有冲突的属性或方法

类似问题参考:
How to overcome “same JVM signature” error when implementing a Java interface?

1.2. 可能的解决方案

以上的问题根本原因已经提及了,就是因为最终的签名冲突了。所以只要能解决签名的问题,那么就不会存在此问题了。

1.2.1. 修改签名

幸运的是,在kotlin中允许通过注解修改编译后的方法名

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值