[英]Kotlin check if elements in list with erased type are instances of a Java class
我有一个存储resultClass
的 class,我想做一些类型检查并确保用户在调用getTypeSafeResults
function 时获得类型安全列表。
class MyClass<T>(
private val resultClass: Class<T>
){
fun getTypeSafeResults() : List<T> {
val results: List<Any?> = remoteFetchResults()
return results.filterIsInstance(resultClass)
}
}
这个 API 必须是 Java 友好的,因此 resultClass 是 Java ZA2F2ED4F8EBC40AB61A2。
But, when resultClass=Integer::class.java
/ resultClass=Long::class.java
, and the results contain the Kotlin version of these eg kotlin.Int / kotlin.Long, they do not match the filterIsInstance(resultClass)
.
有没有办法手动检查resultClass是否是Kotlin类型的Java版本? 我已经尝试过下面这段代码,但没有运气:
(当it
是 kotlin Long 时, it.javaClass.kotlin="class kotlin.Long"
但resultClass="long"
)
fun getTypeSafeResults(results: List<Any?>) : List<T> {
return results.map {
uncheckedCast(
if (resultClass.isAssignableFrom(it.javaClass)) { // doesn't match kotlin long to java Long
it
} else if (it.javaClass.kotlin == resultClass) { // doesn't match kotlin long to java Long
it
} else {
throw Exception("Attempted to cast result of type ${it.javaClass} to $resultClass")
}
)
}
}
我做了一些实验来更好地理解发生了什么。
所有这些都正确找到了 42:
val list = listOf(42, 32L, "bob")
println(list.filter { it::class == Int::class })
println(list.filter { it::class == java.lang.Integer::class.java.kotlin })
println(list.filter { it::class == Int::class.java.kotlin })
println(list.filter { it.javaClass == Int::class.javaObjectType })
println(list.filter { it.javaClass == java.lang.Integer::class.java })
只有这不会:
println(list.filter { it.javaClass == Int::class.java })
因此,您可以做的是确保您在用户给您的 class 上使用javaObjectType
:
class MyClass<T : Any>(
resultClass: Class<T>
){
private val effectiveClass = resultClass.kotlin.javaObjectType
fun getTypeSafeResults() : List<T> {
val results: List<Any?> = remoteFetchResults()
return results.filterIsInstance(effectiveClass)
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.