Kotlin中泛型类型等效于*::class.java的写法是什么?
Kotlin 获取带泛型参数的类型定义方法
JVM平台的泛型存在运行时类型擦除机制,类名::class.java只能获取擦除了泛型信息的原始类Class对象,因此Map<String, String>::class.java这类写法无法通过编译。要获取携带泛型参数的类型,可根据使用场景选择以下等效写法:
JSON反序列化场景常用写法
方法1:使用框架自带的类型引用类
Jackson、Gson等常用JSON库都提供了专门用来保留泛型信息的类型包装类,通过匿名内部类实例即可获取带泛型的类型,是最通用的写法:
// Jackson 示例 val map = mapper.readValue( decodedString, object : com.fasterxml.jackson.core.type.TypeReference<Map<String, String>>() {} ) // Gson 示例 val map = Gson().fromJson<Map<String, String>>( decodedString, object : com.google.gson.reflect.TypeToken<Map<String, String>>() {}.type )
这种写法的原理是:匿名内部类会在字节码中保留父类/接口上声明的泛型实参,框架可以通过反射读取到这部分信息。
方法2:用Jackson的类型工厂构造类型
如果不想写匿名内部类,也可以直接调用Jackson自带的类型工厂方法,手动构造带泛型的JavaType对象:
val mapType = mapper.typeFactory.constructMapType( Map::class.java, String::class.java, String::class.java ) val map = mapper.readValue(decodedString, mapType)
标准库通用写法(不依赖第三方框架)
Kotlin 1.3及以上版本提供了typeOf内联函数,可以直接在纯标准库环境下获取带泛型的类型,再转换为JVM层的Type对象使用:
import kotlin.reflect.javaType import kotlin.reflect.typeOf // 1.6及以上Kotlin版本可直接使用,低版本需要加@OptIn(ExperimentalStdlibApi::class) val mapType: java.lang.reflect.Type = typeOf<Map<String, String>>().javaType val map = mapper.readValue(decodedString, mapType)
注意:
::class.java语法本身只支持获取无泛型的原始类对象,永远无法直接通过这个语法拿到带泛型参数的类型,不存在Map<String, String>::class.java这类合法写法。
内容的提问来源于stack exchange,提问作者Sjoerd222888
相关产品推荐
相关产品推荐

