我想从通用类型 T
中获取类属性。
我已决定扩展到 Any
但出现错误。
https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-any/index.html#extension-properties
我有以下代码:
class FirebaseDBRepo<T : Any>(val child:String) {
private var callback: FirebaseDatabaseRepositoryCallback<T>? = null
private val ref: DatabaseReference
private val listener = object : ValueEventListener {
override fun onDataChange(dataSnapshot: DataSnapshot) {
//T::class.java is showing the error cannot use t as reified type parameter use class instead
val gameDS = dataSnapshot.getValue(T::class.java)
callback!!.onSuccess(gameDS!!)
}
override fun onCancelled(databaseError: DatabaseError) {
}
}
init {
ref = FirebaseDatabase.getInstance().reference.child(child)
}
fun addListener(callback: FirebaseDatabaseRepositoryCallback<T>) {
this.callback = callback
ref.addValueEventListener(listener)
}
fun removeListener() {
ref.removeEventListener(listener)
}
}
最佳答案
您只能在具体化的变量上获取类。同样的事情发生在 java 中,但消息略有不同:
public <T> void x(){
T t = T.class.newInstance();
}
在 Java 中,您可以这样解决:
public <T> void x(Class<T> cls){
T t = cls.newInstance();
}
这同样适用于 Kotlin 和任何调用。在大多数情况下,您需要获取一个类实例。但是,Kotlin 支持使用关键字具体化泛型,但仅限于内联泛型函数。您可以传递一个类,但在函数中,只需使用 reified 关键字就非常容易。
因为你不能用具体化的泛型声明一个类,这意味着这是无效的:
class SomeClass<reified T>
但它对内联函数有效,这意味着您可以:
inline fun <reified T> someFunction()
所以你有两个选择。但是由于您扩展了监听器,因此将泛型添加到函数的第一个选项不是一个选项。您不能使用泛型覆盖非泛型方法。它不会编译。
剩下的是第二个选项,不幸的是,这个选项有点老套;将类传递给构造函数。所以它应该是这样的:
class FirebaseDBRepo<T : Any>(val child: String, private val cls: Class<T>) {
现在,我不使用 Firebase,所以我不知道你要传递什么类,所以对于下一个示例,我只使用 String
.
Kotlin 支持某种类型的最小化,而无需转向原始类型。这:
val t = FirebaseDBRepo<String>("", String::class.java)
可以缩短为:
val t = FirebaseDBRepo("", String::class.java)
两种情况下的推断类型都是 FirebaseDBRepo<String>
.
关于android - 如何在 Kotlin 中获取泛型类型参数的类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52446900/