我有以下代码:
class FirebaseDBRepo(val child:String) {
private var callback: FirebaseDatabaseRepositoryCallback? = 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) {
this.callback = callback
ref.addValueEventListener(listener)
}
fun removeListener() {
ref.removeEventListener(listener)
}
}
解决方法:
您只能在已知的变量上获取该类.在java中也发生了同样的事情,但是消息略有不同:
public void x(){
T t = T.class.newInstance();
}
在Java中,你可以解决这个问题:
public void x(Class cls){
T t = cls.newInstance();
}
这同样适用于Kotlin和任何电话.在大多数情况下,您需要获取类实例.但是,Kotlin使用关键字支持reified泛型,但仅支持内联泛型函数.你可以传递一个类,但在函数中,只需使用reified关键字就可以了.
因为你不能声明一个具有reified泛型的类,这意味着这是无效的:
class SomeClass
但它对内联函数有效,这意味着你可以这样做:
inline fun someFunction()
所以你有两个选择.但是,由于您扩展了一个监听器,因此将该泛型添加到该函数的第一个选项不是一个选项.您不能使用泛型覆盖非泛型方法.它不会编译.
这留下了第二种选择,不幸的是,这种选择相当苛刻;将类传递给构造函数.所以看起来应该是这样的:
class FirebaseDBRepo(val child: String, private val cls: Class) {
现在,我不使用Firebase,所以我不知道你要传递哪些类,所以对于下一个例子,我只使用String.
Kotlin支持某种类型的最小化,而不需要转换为原始类型.这个:
val t = FirebaseDBRepo("", String::class.java)
可以缩短到这个:
val t = FirebaseDBRepo("", String::class.java)
两种情况下的推断类型都是FirebaseDBRepo< String>.
标签:kotlin,firebase-realtime-database,generics,android
来源: https://codeday.me/bug/20190722/1500064.html