Kotlin值类在泛型场景下与Java/Groovy的互操作问题咨询
解决方案
问题根因
- Kotlin 内联值类(
@JvmInline value class)的主构造函数默认私有,Java/Groovy 无法直接通过new关键字创建实例 - 泛型场景下值类不会被内联,Kotlin 侧会期望收到装箱后的
ValueClass实例,直接返回底层String类型会在运行时触发类型转换异常 - 接口方法标注
@JvmName后,方法签名会固定为返回值类类型,不再自动内联为底层类型,因此实现类不能直接返回底层类型
修复方案
前置优化(可选但推荐)
先在 Kotlin 侧的值类中添加 JVM 静态工厂方法,方便 Java/Groovy 调用:
@JvmInline value class ValueClass(val id: String) { companion object { @JvmStatic fun of(id: String): ValueClass = ValueClass(id) } }
如果不想修改原有 Kotlin 代码,也可以直接调用 Kotlin 自动生成的静态装箱方法ValueClass.box(底层类型)创建实例。
Java 实现修正
class ValueClassListProviderImplJava implements ValueClassListProvider { public List<ValueClass> values() { return Arrays.asList(ValueClass.of("1")); } public ValueClass value() { return ValueClass.of("1"); } }
Groovy 实现修正
class ValueClassListProviderImplGroovy implements ValueClassListProvider { List<ValueClass> values() { return [ValueClass.of("1"), ValueClass.of("2")] } ValueClass value() { return ValueClass.of("1") } }
补充说明
非泛型场景下如果没有标注@JvmName,值类返回值会自动内联为底层类型,此时 Java/Groovy 可以直接返回底层类型(比如String),但泛型场景下因为类型擦除限制,必须使用装箱后的值类实例。
内容的提问来源于stack exchange,提问作者Aleksander Ihnatowicz
相关产品推荐
相关产品推荐

