gpt4 book ai didi

java - Kotlin:如何在运行时的 OneClass 中获取实际的泛型类型 T

转载 作者:行者123 更新时间:2023-12-02 13:38:51 25 4
gpt4 key购买 nike

friend 们!
我是 Kotlin 的新手,现在有一个问题。
现在我想在 OneClass 中获取泛型类型 T,这里有一些外围代码。

// IDatabase.kt
package com.ra
abstract class IDatabase<T> { }
// Database1.kt
import kotlin.reflect.jvm.javaType
open class Database1<T>: IDatabase<T>() {
val tClass = this::class.supertypes[0].arguments[0].type!!.javaType as Class<T>
}
// Database2.kt
import kotlin.reflect.jvm.javaType
open class Database2<T>: IDatabase<T>() {
val tClass = this::class.supertypes[0].arguments[0].type!!.javaType as Class<T>
// just wrap a `object` to confort the user
companion object {
fun <T> getInstance(): Database2<T> {
return object: Database2<T>() {}
}
}
}

下面是下面的主要函数,我在其中测试了三种尝试获取泛型类型 T 的方法,结果都在代码下的注释中。
fun main(args: Array<String>) {
val database1 = Database1<String>()
println(database1.tClass.canonicalName)
/**
* Exception in thread "main" java.lang.ClassCastException:
* sun.reflect.generics.reflectiveObjects.TypeVariableImpl cannot be cast to java.lang.Class
* at com.ra.Database1.<init>(Database1.kt:6)
* at com.ra.MainKt.main(Main.kt:4)
*/

val database2 = object: Database1<String>() {}
print(database2.tClass.canonicalName)
/**
* java.lang.String
*/

val database3 = Database2.getInstance<String>()
println(database3.tClass.canonicalName)
/**
* Exception in thread "main" java.lang.ClassCastException:
* sun.reflect.generics.reflectiveObjects.TypeVariableImpl cannot be cast to java.lang.Class
* at com.ra.Database2.<init>(Database2.kt:6)
* at com.ra.Database2$Companion$getInstance$1.<init>(Database2.kt:10)
* at com.ra.Database2$Companion.getInstance(Database2.kt:10)
* at com.ra.MainKt.main(Main.kt:19)
*/
}

如您所见,只有一种成功方式——方式 2。但它一点也不漂亮。因为我想将它包装在一个静态函数中(就像第 3 种方式一样),它又失败了。

所以这是我的问题:
  • 为什么会出现错误 ClassCastException发生?
  • 有没有更漂亮的方法来解决这个问题?如果喜欢 C# 的解决方案,那就太好了。
  • 我知道问题的原因是JVM在编译期间删除了泛型类型,所以我想知道(只是好奇)什么时候可以改变?或者 Kotlin 或其他 JVM 语言可能会记录泛型类型信息?如果有任何请告诉我。我已经受够了类型删除...
  • 最佳答案

    它可以与具体的内联函数一起使用

    package com.ba

    import kotlin.reflect.KClass

    abstract class IDatabase<T> { }

    open class Database2<T: Any>(val tClass: KClass<T>) : IDatabase<T>() {
    // just wrap a `object` to confort the user
    companion object {
    inline fun <reified T: Any> getInstance(): Database2<T> = Database2(T::class)
    }
    }

    fun main(args: Array<String>) {
    val databaseString = Database2.getInstance<String>()
    println(databaseString.tClass)

    val databaseInt = Database2.getInstance<Int>()
    println(databaseInt.tClass)
    }

    输出
    class kotlin.String
    class kotlin.Int

    关于java - Kotlin:如何在运行时的 OneClass<T> 中获取实际的泛型类型 T,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48160784/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com