Kotlin值类作为Service接口参数,Java调用报错的解决办法问询
问题描述
定义了Kotlin的value class实体:
value class EntityId(val id: Long) {}
以及服务接口:
interface Service { fun do(entityId: EntityId) }
完成接口实现后,在Java代码中调用时:
{ ... EntityId id = new EntityId(1L); service.do(id); // service为接口实例 }
出现编译错误。原因是Kotlin编译器会为value class生成参数为Long的桥接方法fun do(entityId: Long),但尝试直接传入Long值调用service.do(1L)时,又报如下错误:
java: cannot find symbol symbol: method do(long)
推测是编译时接口未生成对应桥接方法,目前只能考虑将value class替换为data class,但希望保留value class,寻求可行解决办法。
解决办法
1. 给接口手动加桥接方法
在Kotlin的Service接口里,显式添加一个接收Long参数的重载方法,内部直接调用原方法:
interface Service { fun do(entityId: EntityId) // 专门给Java调用加的桥接方法 fun do(id: Long) = do(EntityId(id)) }
这样Java里不管传EntityId实例还是直接传Long值,都能正常调用。
2. 显式添加@JvmInline注解
虽然value class默认是内联的,但显式加上@JvmInline注解能让编译器更明确地处理Java互操作性,注意Kotlin版本要在1.5及以上:
@JvmInline value class EntityId(val id: Long) {}
重新编译项目后,再试试在Java里直接传Long值调用。
3. Java侧通过component1()取原始值调用
如果不想改Kotlin代码,Java里可以先从EntityId实例里取出原始Long值再调用:
EntityId id = new EntityId(1L); service.do(id.component1());
内容的提问来源于stack exchange,提问作者Artur Shaikhutdinov
相关产品推荐
相关产品推荐

