Kotlin类的平等失败了

时间:2016-03-18 22:40:18

标签: reflection kotlin

以下代码段显示了测试从不同来源获得的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方法。

文档说:

  

返回与给定KClass实例对应的Java Class实例。在原始类型的情况下,它返回相应的包装类。

即。 c.javaObjectType == c1.javaObjectType是真的

但这并不能证明为什么具有相同字符串表示的KClass不同。至少它令人困惑。在文档中注意这一点是个好主意。

1 个答案:

答案 0 :(得分:4)

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

解决方法是使用KClass的{​​{1}}属性,即使对于编译为Java原语的Kotlin类型,它也将返回Java类(非基本类型):

javaObjectType

我同意这种语义相当混乱,我filed an issue关于它。

此外, fun sameClass(c1: KClass<*>, c2: KClass<*>) = c1.javaObjectType == c2.javaObjectType sameClass(Int::class, (1 as Any?)!!.javaClass.kotlin) //true 并不反映Kotlin类型的可空性,如果您需要精确处理声明的Kotlin类型,则需要使用KClass,这样做。

UPD:此问题已被标记为已解决,并且自1.0.2以来KType KDoc中解释了相等性。