2013-09-11 4 views
6

नीचे (जावा) कोड कानूनी है?'==' ऑपरेटर के साथ ऑब्जेक्ट्स और प्राइमेटिव की तुलना करना कानूनी कब है?

class Test { 
    Object foo() {return "";} 
    boolean bar() {return foo() == true;} 
} 

यह जेडीके 6 के खिलाफ संकलित नहीं होगा लेकिन 7+ पर ठीक लगता है। क्या स्पेक बदल गया? एक बग तय किया गया था? मैं http://bugs.eclipse.org/bugs/show_bug.cgi?id=416950 पर चर्चा कर रहा हूं और इस पर किसी भी तरह से जा सकता हूं।

+2

इस पिछली पोस्ट की जांच करें, [जावा 6 और जावा 7 ऑटोबॉक्सिंग में अंतर] (http://stackoverflow.com/questions/16119638/differences-in-auto-unboxing-between-java-6-vs-java-7) – nachokk

उत्तर

1

यह पता चला है के रूप में, यह कानूनी नहीं संकलन समय प्रकार 'वस्तु' की अभिव्यक्ति के साथ एक आदिम तुलना करने के लिए है। JLS 15.21 स्पष्ट रूप से यह मनाही:

समानता ऑपरेटरों सांख्यिक प्रकार के दो ऑपरेंड कि परिवर्तनीय (§5.1.8) कर रहे हैं, या प्रकार बूलियन या बूलियन, की दो ऑपरेंड या दो ऑपरेंड कि में से प्रत्येक की तुलना करने के लिए इस्तेमाल किया जा सकता है या तो संदर्भ प्रकार या शून्य प्रकार। अन्य सभी मामलों का परिणाम संकलन-समय त्रुटि में होता है।

एक्लिप्स कंपाइलर जावा संस्करण की परवाह किए बिना त्रुटि को झंडे करता है।जावा 7 के लिए, ओरेकल जेडीके और ओपनजेडीके दोनों गलती से कोड को संकलित करने की अनुमति देते हैं। ओरेकल और ओपन जेडीके में यह bug संस्करण 8 में ठीक किया गया है।

संक्षेप में, यह भयानक तुलना स्पेक के अनुसार अवैध है और केवल भाषा संस्करण लक्ष्यों के एक विशेष सबसेट के लिए कंपेलरों के कुछ सबसेट पर संकलित होगी। जावा 4- या 8+ पर कभी काम नहीं करेगा। अन्य उत्तरों में संदर्भित कास्टिंग रूपांतरण केवल '=' ऑपरेटर पर लागू होते हैं, न कि '==' पर। 15.21.3 केवल दो संदर्भ संचालन पर लागू होता है।

0

यहाँ

java version "1.7.0_25" 
Java(TM) SE Runtime Environment (build 1.7.0_25-b17) 
Java HotSpot(TM) 64-Bit Server VM (build 23.25-b01, mixed mode) 

यह एक Boolean कि अनबॉक्स्ड हो जाता है में लौटे String परिवर्तित किया जा रहा है के साथ संकलित संदर्भ

class Test { 
    Test(); 
    Code: 
     0: aload_0 
     1: invokespecial #1     // Method java/lang/Object."<init>": 
     4: return 

    java.lang.Object foo(); 
    Code: 
     0: ldc   #2     // String 
     2: areturn 

    boolean bar(); 
    Code: 
     0: aload_0 
     1: invokevirtual #3     // Method foo:()Ljava/lang/Object; 
     4: iconst_1 
     5: invokestatic #4     // Method java/lang/Boolean.valueOf: 
     8: if_acmpne  15 
     11: iconst_1 
     12: goto   16 
     15: iconst_0 
     16: ireturn 
} 

के लिए बाइट कोड है। संदर्भ समानता के बारे में

3

JLS जावा के बीच 6 & 7 बदल नहीं करता है:

Chapter 15.21.3: Reference Equality Operators == and !=:

तो एक समानता ऑपरेटर की ऑपरेंड या तो संदर्भ प्रकार या अशक्त प्रकार के दोनों कर रहे हैं, तो ऑपरेशन वस्तु समानता है।

यह एक संकलन-समय त्रुटि है यदि के प्रकार को परिवर्तित करना असंभव है या तो एक कास्टिंग रूपांतरण (§5.5) द्वारा दूसरे के प्रकार के लिए संचालित करना असंभव है। दो ऑपरेटरों के रन-टाइम मान असमान होंगे।

हालांकि मैंने Chapter 5.5: Casting Conversion पर कुछ बदलाव देखा। कास्टिंग वस्तु को बूलियन जावा 7 पर मुक्केबाजी सम्मेलन के रूप में वर्गीकृत किया गया प्रतीत होता:

एक आदिम प्रकार का एक अभिव्यक्ति कास्टिंग रूपांतरण मुक्केबाजी रूपांतरण द्वारा त्रुटि के बिना एक संदर्भ प्रकार के गुजरना पड़ सकता है।

enter image description here

⊡ का प्रतीक है बॉक्सिंग रूपांतरण

इसलिए क्योंकि आदिम trueObject लिए casted जा सकता है, अपने समानता अभिव्यक्ति संदर्भ समानता के रूप में जावा 7 पर वर्गीकृत किया जा सकता है, और संकलक त्रुटि उपज नहीं है

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