如何在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所以,如果你做这样的事情:
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
- 通过使用在超类中定义的相同名称的var来覆盖在接口中定义的val
- 有问题写在Kotlin的EditText
- Kotlin和Android TextWatcher具有CharSequence / String替换功能
- RecyclerView.Adapter-错误:公共函数在Kotlin中公开它的内部返回类型
- 什么时候应该喜欢Kotlin扩展功能?
- 如何使用Lamba表达式使Java方法调用在Kotlin中不那么冗长?
- 当选择的项目视图为空时,Kotlin在Android上崩溃
- 如何将实例类型数据存储在Kotlin的实例字段中?
- 如何从Kotlin / Java中运行Kotlin-Script(.kts)文件?