友! 我是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
会发生?答案 0 :(得分:1)
它可以使用内联函数
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