2016-03-18 13 views
4

次のスニペットは、さまざまなソースから入手したKotlin KClass参照の等価性をテストした結果を示しています。それらの文字列の表現は同じです。しかし、彼らのJavaクラスは異なっています。 c,c0およびc1が等しいと予想される。しかし何らかの理由で彼らはそうではありません。Kotlinクラスの等価性が失敗する

ニュアンスがありますかバグですか?それがバグでなければ、KClassの等価性をテストする信頼できる方法は何ですか?

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) 
} 

EDIT:

回避策はKClass.javaObjectType方法を使用することです。

ドキュメントは言う:

与えKClassインスタンスに対応するJavaクラスのインスタンスを返します

。プリミティブ型の場合、対応するラッパークラスを返します。

e.e.e. c.javaObjectType == c1.javaObjectTypeが真である

しかし、同じ文字列表現を持つKClassが異なる理由は正当ではありません。少なくともそれは混乱しています。そして、それについてドキュメントに書いておくことをお勧めします。

答えて

3

KClassは、同じKotlinタイプではなく、同じJavaタイプに対応しているため、等価とみなされます。 intjava.lang.Integerの場合はfalseです。

回避策も、JavaのプリミティブにコンパイルKotlinタイプのJavaクラス(プリミティブではないタイプ)を返しますKClassjavaObjectTypeプロパティ、使用することです:

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

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

私はこの意味はかなり混乱していることに同意し、私はそれについて約filed an issueです。

また、KClassは、KotlinタイプのNULL可能性を反映しておらず、宣言されたKotlinタイプを正確に処理する必要がある場合は、KTypeを使用する必要があります。


UPD:問題が修正としてマークされている、と平等が1.0.2以降KClass.equals KDOCに説明されています。

+0

null許容度はクラスの比較に関連していますか?私が理解しているように、クラスはnull可能ではありません。式の型は可能です。しかし、私たちはクラスの平等をテストしますが、表現はテストしません。 –

+0

@ MarkusMarvell、あなたは正しいです、そうではありません。私は、「KClass」はKotlinの型を宣言していないことを別のことのヒントとして述べている。私はそれをもっと明確にするために、この声明を改革するつもりです。 – hotkey

関連する問題