以下代码段显示了测试从不同来源获得的Kotlin KClass
引用的相等性的结果。他们的字符串表示是相同的。但他们的java类是不同的。预计c
,c0
和c1
相同。但由于某种原因,他们不是。
是否有一些细微差别或它是一个错误?如果它不是一个错误,那么测试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
不同。至少它令人困惑。在文档中注意这一点是个好主意。
答案 0 :(得分:4)
在你的情况下,相等失败是因为当KClass
es对应于相同的Java类型而不是相同的Kotlin类型时,它们被认为是相等的。对于int
和java.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中解释了相等性。