Kotlin泛型类中如何获取参数T的实际类型?
解决Kotlin泛型Deserializer获取实际类型的问题
这个问题其实是Kotlin(以及Java)泛型类型擦除导致的经典坑——编译后泛型参数T的实际类型信息会被擦除,所以你直接在Deserializer里创建TypeToken<T>拿到的只是占位符T,不是实际传入的类类型。下面给你几个靠谱的解决办法:
1. 构造函数显式传入类型信息
最直接的方式是让使用者在创建Deserializer的时候,把实际的类型信息传进来,比如传入TypeToken或者Class:
传入TypeToken(支持泛型类,比如List<User>)
class Deserializer<T : Any>(private val typeToken: TypeToken<T>) : ResponseDeserializable<T> { override fun deserialize(reader: Reader): T? { return Gson().fromJson(reader, typeToken.type) } } // 使用示例: val userListDeserializer = Deserializer(object : TypeToken<List<User>>() {}) val userDeserializer = Deserializer(object : TypeToken<User>() {})
传入Class<T>(仅支持非泛型的具体类)
如果你的T是普通类(不是带泛型参数的类,比如List<User>这种就不行),可以直接传Class,代码更简洁:
class Deserializer<T : Any>(private val clazz: Class<T>) : ResponseDeserializable<T> { override fun deserialize(reader: Reader): T? { return Gson().fromJson(reader, clazz) } } // 使用示例: val userDeserializer = Deserializer(User::class.java)
2. 利用Kotlin的reified泛型简化调用
Kotlin的reified关键字可以让泛型类型在运行时保留信息,配合inline函数使用,能让调用方不用手动创建TypeToken:
// 先写一个inline辅助函数创建Deserializer inline fun <reified T : Any> createDeserializer(): Deserializer<T> { return Deserializer(object : TypeToken<T>() {}) } // Deserializer类和之前传入TypeToken的版本一样 class Deserializer<T : Any>(private val typeToken: TypeToken<T>) : ResponseDeserializable<T> { override fun deserialize(reader: Reader): T? { return Gson().fromJson(reader, typeToken.type) } } // 使用的时候超级简洁: val userDeserializer = createDeserializer<User>() val userListDeserializer = createDeserializer<List<User>>()
这里的核心是reified让T的实际类型在inline函数内可见,所以创建的TypeToken<T>能正确拿到实际类型。
3. 通过子类继承获取类型(适合固定类型的场景)
如果你的Deserializer是针对某个固定类型使用的,可以创建一个具体的子类,在父类中通过反射获取泛型参数:
open class Deserializer<T : Any> : ResponseDeserializable<T> { // 通过反射获取父类的泛型参数类型 private val type = (javaClass.genericSuperclass as ParameterizedType).actualTypeArguments[0] override fun deserialize(reader: Reader): T? { return Gson().fromJson(reader, type) } } // 创建具体的子类,指定泛型类型 class UserDeserializer : Deserializer<User>() class UserListDeserializer : Deserializer<List<User>>() // 使用示例: val userDeserializer = UserDeserializer() val userListDeserializer = UserListDeserializer()
注意:这个方法不能直接用Deserializer<User>(),必须创建子类,否则genericSuperclass不是ParameterizedType会抛出异常。
内容的提问来源于stack exchange,提问作者William
相关产品推荐
相关产品推荐

