2017-10-10 25 views
8

कोटलिन 1.1 दिया गया। कुछ वर्ग के एक instance के लिए, instance::class.java और instance.javaClass लगभग बराबर होने लगते हैं:उदाहरण :: class.java बनाम example.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 negligibly कम है, लेकिन 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

मुझे लगता है कि मैंने कहीं पढ़ा है कि 'जावा क्लास' को बहिष्कृत माना जाना है, लेकिन मुझे अभी यह नहीं मिल रहा है। – marstran

उत्तर

8

इन दो निर्माणों में अंतर यह है कि, स्थैतिक की अभिव्यक्ति foo के लिए (घोषित या अनुमानित) टाइप Foo है:

  • foo.javaClass रूप Class<Foo>

  • foo::class.java लिखा गया Class<out Foo>

    के रूप में लिखा गया

वास्तव में, उत्तरार्द्ध मी अयस्क सटीक, क्योंकि वास्तविक मूल्य foo का मूल्यांकन Foo का उदाहरण नहीं हो सकता है, लेकिन इसके उपप्रकारों में से एक (और यह बिल्कुल है जो covariant out Foo द्वारा दर्शाया गया है)।

के रूप में सही ढंग से प्रश्न पर टिप्पणी में उल्लेख किया @marstran, .javaClass एक बार के रूप में है, क्योंकि यह था बहिष्कार कर दिया करने के लिए (Kotlin 1.1 RC announcement देखें), क्योंकि यह प्रकार सुरक्षा (देखें नीचे) तोड़ सकते हैं माना जाता था, लेकिन यह बाद में छोड़ दिया गया था ::class.java के विकल्प के साथ व्यापक रूप से उपयोग और इसे बदलने के लिए कोड में स्पष्ट अनचेक किए गए जानवरों को जोड़ने की आवश्यकता होगी।

इसके अलावा, इस सवाल का जवाब नीचे टिप्पणी देखें: (link)


कृपया ध्यान दें कि Int.javaClassInt के प्रकार निरूपित नहीं है, लेकिन इसके बजाय Int के साथी वस्तु के जावा वर्ग है। जबकि Int::class.java एक अनबाउंड क्लास संदर्भ है और इस प्रकार को इंगित करता है। इसे .javaClass के साथ प्राप्त करने के लिए, आपको इसे 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 प्राप्त हुई थी (Class<Foo> तो KClass<Foo> करने के लिए परिवर्तित) संकलक हमें in Foo प्रक्षेपण के साथ इसका इस्तेमाल करने की अनुमति देता है।

संबंधित मुद्दे