如何在Kotlin中获得泛型参数类

Firebase的snapshot.getValue()预计将被调用,如下所示:

 snapshot?.getValue(Person::class.java) 

不过,我想用一个通过类声明传递给类的泛型参数替换Person

 DataQuery<T : IModel> 

并使用该泛型参数来做这样的事情:

 snapshot?.getValue(T::class.java) 

但是当我尝试,我得到一个错误说明

只有类可以用在类文字的左侧

是否有可能像在C#中的泛型参数提供一个类的约束,还是有一些其他的语法,我可以用来获得泛型参数的类型信息?

你需要的是通用参数的修饰符,你可以在这里阅读。 https://kotlinlang.org/docs/reference/inline-functions.html#reified-type-parameters所以,如果你做这样的事情&#xFF1A;

 inline fun <reified T : Any>T.logTag() = T::class.java.simpleName 

你将得到实际的调用者类的名字,而不是“对象”。

对于具有泛型参数T的类,不能这样做,因为JVM没有类型信息,因为JVM会删除类型信息。 因此这样的代码不能工作:

 class Storage<T: Any> { val snapshot: Snapshot? = ... fun retrieveSomething(): T? { return snapshot?.getValue(T::class.java) // ERROR "only classes can be used..." } } 

但是,如果T的类型在内联函数中被指定和使用,则可以使其工作:

 class Storage { val snapshot: Snapshot? = ... inline fun <reified T: Any> retrieveSomething(): T? { return snapshot?.getValue(T::class.java) } } 

请注意,内联函数如果公开只能访问该类的公共成员。 但是可以有两个函数变体,一个接收一个不是内联的类参数,并且访问私有内部函数,另一个内联辅助函数从推断的类型参数中进行确定:

 class Storage { private val snapshot: Snapshot? = ... fun <T: Any> retrieveSomething(ofClass: Class<T>): T? { return snapshot?.getValue(ofClass) } inline fun <reified T: Any> retrieveSomething(): T? { return retrieveSomething(T::class.java) } } 

您也可以使用KClass而不是Class这样只有Kotlin的调用者才可以使用MyClass::class而不是MyClass::class.java

如果您希望类与泛型上的内联方法配合使用(意味着类Storage只存储类型T对象):

 class Storage <T: Any> { val snapshot: Snapshot? = ... inline fun <reified R: T> retrieveSomething(): R? { return snapshot?.getValue(R::class.java) } } 

内联函数中通用类型的链接: https : //kotlinlang.org/docs/reference/inline-functions.html#reified-type-parameters