以下代码段显示了测试KClass从不同来源获得的Kotlin 引用的相等性的结果.他们的字符串表示是相同的.但他们的java类是不同的.期待c,c0并且c1是平等的.但由于某种原因,他们不是.
有一些细微差别或它是一个错误?如果它不是一个错误,那么测试KClasses 相等性的可靠方法是什么?
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)
}
Run Code Online (Sandbox Code Playgroud)
编辑:
解决方法是使用KClass.javaObjectType方法.
文档说:
返回与给定KClass实例对应的Java Class实例.在原始类型的情况下,它返回相应的包装类.
我c.javaObjectType == c1.javaObjectType是真的
但这并不能证明为什么KClass具有相同字符串表示的es是不同的.至少它令人困惑.在文档中注意这一点是个好主意.
在您的情况下,相等性失败,因为KClass当es对应于相同的Java类型而不是相同的Kotlin类型时,它们被视为相等。对于int和,这是错误的java.lang.Integer。
解决方法是使用KClass的javaObjectType属性,即使对于编译成Java原语的Kotlin类型,它也将返回Java类(不是原语类型):
fun sameClass(c1: KClass<*>, c2: KClass<*>) = c1.javaObjectType == c2.javaObjectType
sameClass(Int::class, (1 as Any?)!!.javaClass.kotlin) //true
Run Code Online (Sandbox Code Playgroud)
我同意这种语义相当混乱,因此我提出了一个问题。
另外,KClass它不能反映Kotlin类型的可为空性,并且如果您需要精确地使用声明的Kotlin类型,则需要使用KType,它可以。
UPD:此问题已标记为已修复,并且KClass.equals自1.0.2起在KDoc中说明了该等同性。
| 归档时间: |
|
| 查看次数: |
530 次 |
| 最近记录: |