You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 06:34:56