有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

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

我有一个存储resultClass的类,我想做一些类型检查,确保用户在调用getTypeSafeResults函数时获得一个类型安全列表

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类

但是,当resultClass=Integer::class.java/resultClass=Long::class.java时,结果包含这些的Kotlin版本,例如Kotlin。内特/科特林。Long,它们与filterIsInstance(resultClass)不匹配

有没有办法手动检查resultClass是否为Kotlin类型的Java版本?我尝试了下面这段话,但没有成功:

(当it是kotlin长时,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")
            }
        )
    }
}

共 (1) 个答案

  1. # 1 楼答案

    我做了一些实验来更好地了解发生了什么

    所有这些都正确地找到了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 })
    

    因此,您可以做的是确保在用户提供给您的类上使用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)
        }
    }