在Kotlin的运行时获取通用类型

时间:2019-03-02 18:20:19

标签: generics kotlin types

如何正确执行?

因为这不起作用。 我的null结果总是class SomeClass<T>()

当我尝试执行SomeClass<Int>或类似的操作时,由于我不知道如何正确获取Generic的类型,因此得到空值。

我已经尝试在类中创建字段,但是我想避免在此类中创建字段

    @Suppress("UNCHECKED_CAST")
fun <T : Any> SomeClass<T>.defaultSerializer(): KSerializer<T>? = when (this) {
    String::class -> StringSerializer
    Char::class -> CharSerializer
    Double::class -> DoubleSerializer
    Float::class -> FloatSerializer
    Long::class -> LongSerializer
    Int::class -> IntSerializer
    Short::class -> ShortSerializer
    Byte::class -> ByteSerializer
    Boolean::class -> BooleanSerializer
    Unit::class -> UnitSerializer
    else -> null
} as KSerializer<T>?

1 个答案:

答案 0 :(得分:0)

您可以使用inline functions with reified types来实现。因此,您基本上处于正确的轨道上,但是您的when语句正在检查this(在您的代码中是SomeClass<T>String::classChar::class等的实例)。相反,您需要比较类本身。

我建议使用的内部方法是打开KClass<T>,然后使用公共内联修饰函数为内部方法提供KClass。例如:

@PublishedApi
internal fun <T : Any> SomeClass<T>.defaultSerializer(
    clazz: KClass<T>
): KSerializer<T>? = when (clazz) {
    String::class -> StringSerializer()
    Char::class -> CharSerializer()
    Double::class -> DoubleSerializer()
    Float::class -> FloatSerializer()
    Long::class -> LongSerializer()
    Int::class -> IntSerializer()
    Short::class -> ShortSerializer()
    Byte::class -> ByteSerializer()
    Boolean::class -> BooleanSerializer()
    Unit::class -> UnitSerializer()
    else -> null
} as KSerializer<T>?

inline fun <reified T: Any> SomeClass<T>.defaultSerializer(): KSerializer<T>? = 
    defaultSerializer(T::class)

然后,给定SomeClass<String>的实例,您可以执行以下操作:

someClassString.defaultSerializer()

使用内部和公共功能分开的原因是避免在使用的所有地方when内联完整的内嵌代码。