科特林阶级平等失败
以下片段显示了从不同来源获得的Kotlin KClass
参考的测试相等性的结果。 他们的字符串表示是相同的。 但是他们的java类是不同的。 预计c
, c0
和c1
是相等的。 但由于某种原因,他们不是。
有一些细微差别,或者是一个错误? 如果这不是一个错误什么是可靠的方法来测试KClass
es的平等?
fun main(args: Array) { 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类实例。 在原始types的情况下,它返回相应的包装类。
即c.javaObjectType == c1.javaObjectType
为true
但是这并不certificate为什么KClass
具有相同的字符串表示方式是不同的。 至少这是令人困惑的。 在文档中注意这个问题是个好主意。
在你的情况下,相等失败,因为当它们对应于相同的Javatypes时, KClass
es被认为是相等的,而不是相同的Kotlintypes。 这对int
和java.lang.Integer
是错误的。
解决方法是使用KClass
的javaObjectType
属性,即使对于编译为Java基元的Kotlintypes,它也将返回Java类(不是基本types):
fun sameClass(c1: KClass<*>, c2: KClass<*>) = c1.javaObjectType == c2.javaObjectType sameClass(Int::class, (1 as Any?)!!.javaClass.kotlin) //true
我同意这个语义是相当混乱的,我提出了一个问题 。
此外, KClass
并不反映Kotlintypes的可空性,如果您需要精确使用Kotlintypes,则需要使用KType
。
UPD:这个问题被标记为固定的,并且在KClass.equals
KDoc自1.0.2以后解释了相等性。