2017-10-10 11 views
8

Given Kotlin 1.1。いくつかのクラスのinstanceについて、instance::class.javainstance.javaClassはほぼ同等であるように見える:インスタンス:: class.javaとインスタンス.javaClass

val i = 0 
println(i::class.java) // int 
println(i.javaClass) // int 
println(i::class.java === i.javaClass) // true 

微妙な違いがしかし、ある:

val c1: Class<out Int> = i::class.java 
val c2: Class<Int> = i.javaClass 

instance.javaClassは無視できるほど短いですが、instance::class.javaはとより一致していますあるタイプの対応する使用。あなたには、いくつかのタイプに.javaClassを使用することができますが、その結果は、あなたが期待するものではないかもしれない:

println(i::class.java === Int::class.java) // true 
println(i.javaClass === Int.javaClass) // false 
println(Int::class.java === Int.javaClass) // false 
println(Int.javaClass) // class kotlin.jvm.internal.IntCompanionObject 

だから、私はより一貫性のため.javaClassを使用しないように優れていることを主張するだろう。それに対して何か議論はありますか?

+1

私は 'javaClass'が廃止予定とみなされているところを読んだと思いますが、今すぐ見つけられません。 – marstran

答えて

8

これら2つの構築物の違いは静的の発現foo(宣言または推論)のためFooを入力することである:Class<Foo>

  • foo::class.javaClass<out Foo>

    として入力される

    • foo.javaClassが入力され

    実際、後者はm fooが評価する実際の値はFooではなく、そのサブタイプのインスタンス(正確には共変量out Fooによって示されているもの)であるため、正確な鉱石です。

    正しく質問にコメントで指摘@marstranとして、それは型の安全性を破ることができるので、.javaClassが一度(下記参照)(Kotlin 1.1 RC announcementを参照)廃止されると考えられたが、それはあったので、それはその後のよう-で残っていました::class.javaの代替と置き換えると、コードに明示的にチェックされていないキャストを追加する必要があります。 (link)


    Int.javaClassIntの種類を示すが、代わりにIntのコンパニオンオブジェクトのJavaクラスでないことに注意してください。

    また、この答えの下のコメントを参照してください。 Int::class.javaはバインドされていないクラス参照であり、型を示します。 で取得するには、Intインスタンスで呼び出す必要があります。 1.javaClass


    ここで、正確に.javaClassがタイプセーフティを破ることができます。このコードは、実行時に休憩に過ぎずコンパイル:

    open class Foo 
    
    class Bar : Foo() { 
        val baz: Int = 0 
    } 
    
    fun main(args: Array<String>) { 
        val someFoo: Foo = Bar() 
        val anotherFoo: Foo = Foo() 
    
        val someFooProperty: KProperty1<in Foo, *> = // 'in Foo' is bad 
          someFoo.javaClass.kotlin.memberProperties.first() 
    
        val someValue = someFooProperty.get(anotherFoo) 
    } 
    

    この例では、kotlin-reflectを使用しています。someFooPropertyBar、ないFooの特性を表すためだが、それはsomeFoo.javaClassから得られたので、コンパイラは、私たちはin Foo突起とそれを使用することができ(Class<Foo>次いでKClass<Foo>換算)

  • 関連する問題