繁体   English   中英

Kotlin 检查列表中具有已擦除类型的元素是否是 Java class 的实例

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM