以下代码段显示了测试从不同来源获得的Kotlin KClass引用是否相等的结果。它们的字符串表示形式是相同的。但是它们的java类不同。期望cc0c1相等。但是由于某些原因,它们不是。

有细微差别还是一个错误?如果不是错误,那么测试KClass es是否相等的可靠方法是什么?

fun main(args: Array<String>) {
    val c = Int::class
    fun test(v0: Any, v1: Any) {
        val c0 = v0.javaClass.kotlin
        val c1 = v1.javaClass.kotlin
        println("c= $c;  c0= $c0;  c1= $c1") // c= class kotlin.Int;  c0= class kotlin.Int;  c1= class kotlin.Int
        println("c= ${c.java};  c0= ${c0.java};  c1= ${c1.java}") // c= int;  c0= class java.lang.Integer;  c1= class java.lang.Integer
        println("c = c0? ${c == c0};  c0 = c1? ${c1 == c0}") // c = c0? false;  c0 = c1? true
    }
    test(11, 22)
}

编辑:

解决方法是使用KClass.javaObjectType方法。

该文档说:



IE。 c.javaObjectType == c1.javaObjectType为true

但这并不能说明为什么具有相同字符串表示形式的KClass是不同的。至少令人困惑。并且最好在文档中对此进行说明。

最佳答案

在您的情况下,相等性失败,因为KClass对应于相同的Java类型而不是相同的Kotlin类型时,它们被视为相等。对于intjava.lang.Integer,这是错误的。

解决方法是使用KClassjavaObjectType属性,即使对于编译成Java原语的Kotlin类型,该属性也将返回Java类(不是原语类型):

 fun sameClass(c1: KClass<*>, c2: KClass<*>) = c1.javaObjectType == c2.javaObjectType

 sameClass(Int::class, (1 as Any?)!!.javaClass.kotlin) //true

我同意这种语义相当困惑,对此我filed an issue

另外,KClass不能反射(reflect)Kotlin类型的可空性,并且如果您需要精确地使用声明的Kotlin类型,则需要使用KType,它可以。

UPD:,此问题已标记为已修复,并且自1.0.2起在KClass.equals KDoc中解释了该等同性。

10-07 18:56