Firebase snapshot.getValue()预计会被调用如下:
snapshot?.getValue(Person::class.java)
Run Code Online (Sandbox Code Playgroud)
但是我想Person用通过类声明传递给类的泛型参数替换,即
class DataQuery<T : IModel>
Run Code Online (Sandbox Code Playgroud)
并使用该泛型参数执行以下操作:
snapshot?.getValue(T::class.java)
Run Code Online (Sandbox Code Playgroud)
但当我尝试我得到一个错误说明
只有类可以在类文字的左侧使用
是否可以像在C#中那样为泛型参数提供类约束,或者是否可以使用其他语法来获取泛型参数的类型信息?
Jay*_*ard 46
对于具有泛型参数T的类,您无法执行此操作,因为您没有T的类型信息,因为JVM会删除类型信息.因此这样的代码不起作用:
class Storage<T: Any> {
val snapshot: Snapshot? = ...
fun retrieveSomething(): T? {
return snapshot?.getValue(T::class.java) // ERROR "only classes can be used..."
}
}
Run Code Online (Sandbox Code Playgroud)
但是,如果T的类型被内联并在内联函数中使用,则可以使其工作:
class Storage {
val snapshot: Snapshot? = ...
inline fun <reified T: Any> retrieveSomething(): T? {
return snapshot?.getValue(T::class.java)
}
}
Run Code Online (Sandbox Code Playgroud)
请注意,如果public,则内联函数只能访问该类的公共成员.但是你可以有两个函数变体,一个接收不是内联的类参数并访问私有内部,另一个内联辅助函数根据推断的类型参数进行相关:
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)
}
}
Run Code Online (Sandbox Code Playgroud)
您也可以使用,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)
}
}
Run Code Online (Sandbox Code Playgroud)
内联函数中已知类型的链接:https://kotlinlang.org/docs/reference/inline-functions.html#reified-type-parameters
Yar*_*lav 19
你需要的是你的通用参数的reified修饰符,你可以在这里阅读它. https://kotlinlang.org/docs/reference/inline-functions.html#reified-type-parameters 所以,如果你这样做:
inline fun <reified T : Any>T.logTag() = T::class.java.simpleName
Run Code Online (Sandbox Code Playgroud)
您将获得实际调用者类的名称,而不是"对象".
mer*_*dan 10
你可以得到它的类类型
snapshot?.getValue((this.javaClass
.genericSuperclass as ParameterizedType)
.actualTypeArguments[0] as Class<T>)
Run Code Online (Sandbox Code Playgroud)
使用typeOf是另一种选择。(Kotlin 1.3 中添加)
例子:
@OptIn(ExperimentalStdlibApi::class)
inline fun <reified T> someMethod(data: T) {
val typeClassifier = typeOf<T>().classifier
if (typeClassifier == List::class) {
//Do something
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
34153 次 |
| 最近记录: |