2015-09-17 18 views
61

निम्नलिखित कोड,जावा 7 में एक इंट-टू-ऑब्जेक्ट तुलना मान्य क्यों है, लेकिन जावा 8 में नहीं?

private boolean compare(Object a, int b) { 
    return a == b; 
} 

जावा 7 में संकलित है, लेकिन यह जावा 8 में निम्न त्रुटि में परिणाम है:

अतुलनीय प्रकार: पूर्णांक और वस्तु

को देखते हुए निम्नलिखित प्रश्न:

Comparing Object and int in Java 7

ऐसा लगता है कि जावा   6 और जावा   8 आपको int और Object की तुलना करने की अनुमति न दें, जबकि 7 करता है। क्या इस पर कोई दस्तावेज है?

मुझे पृष्ठभूमि ज्ञान में दिलचस्पी है जो इन निर्णयों को सूचित करता है। ऐसा लगता है जैसे वे निराश थे या कुछ।

मैं IntelliJ IDEA 14.1.4 का उपयोग जेडीके 1.7.0.51 के साथ कर रहा हूं।

+2

क्या एक्लिप्स में दिखाया गया त्रुटि है (यानी। Ecj का उपयोग करते समय) या जेडीके कंपाइलर द्वारा? मुझे लगता है कि यह ecj में एक त्रुटि है ... – Axel

+2

यदि ऐसा है, तो मुझे लगता है कि जावा 7 ने गलती की है – dragon66

+0

ओरेकल के जावा 7 के साथ, मुझे "असंगत ऑपरेंड प्रकार: ऑब्जेक्ट एंड इंट" मिलता है। क्या आप जावा 7 में संकलित किए गए सटीक कोड को प्रदान कर रहे हैं? –

उत्तर

30

जावा 7 int में autoboxing लागू होता है।

यह व्यवहार मान्यता दी गई थी और बग के रूप में इलाज ओरेकल द्वारा:
JDK-8013357: javac स्वीकार करता गलत बाइनरी तुलना संचालन

प्रासंगिक

private boolean compare(java.lang.Object, int); 
    Code: 
     0: aload_1 
     1: iload_2 
     2: invokestatic #2  // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer; 
     5: if_acmpne  12 
     8: iconst_1 
     9: goto   13 
    12: iconst_0 
    13: ireturn 

मैं build 1.7.0_71-b14

संपादित करें के साथ इस बनाया जेएलएस अनुभाग 15.21 है। जैवैक इसे संदर्भ तुलना के रूप में पेश करता प्रतीत होता है, लेकिन संदर्भ तुलना केवल तभी दी जाती है जब दोनों ऑपरेटिंग संदर्भ प्रकार हैं।
...
जेएलएस धारा 15.21 में बाइनरी तुलना के लिए प्रकार नियम अब सही ढंग से जावैक द्वारा लागू किए जाएंगे। चूंकि जेडीके 5, जेएवीएसी ने प्रोग्राम ऑब्जेक्ट-प्राइमेटिव तुलना के साथ स्वीकार किए हैं जो गलत तरीके से टाइप किए गए हैं जेएलएस 15.21 के अनुसार। ये तुलना अब टाइप प्रकार त्रुटियों के रूप में पहचानी जाएंगी।

7

मुझे javac 1.7.0_75 के साथ संकलन (बूल → बूलियन को ठीक करने) के लिए उदाहरण नहीं मिला, न ही जावैक 1.8.0_60 के साथ। मेरे पास जेडीके 6 नहीं है, लेकिन मुझे नहीं लगता कि इसे वहां भी काम करना चाहिए था। शायद यह एक्सेल संकेतों के रूप में, या जावा के एक अलग मामूली संस्करण में एक बग के रूप में एक पूर्व ecj असंगतता है।

किसी भी घटना में, यदि यह काम करता है, तो यह ऑटोबॉक्सिंग के कारण होता है। यह जावा 8 की तैयारी में वापस आ गया है, क्योंकि स्ट्रीम और ऑटोबॉक्सिंग बहुत अच्छी तरह से मिश्रण नहीं करते हैं। संख्यात्मक, बूलियन और संदर्भ:

22

JLS - Chapter 15. Equality Operators 3 अलग == ऑपरेटरों का उल्लेख है।== ऑपरेटरों के आपके उदाहरण में हो सकते हैं, इसलिए हम निष्कर्ष निकालते हैं कि स्टेटमेंट है।

चलो देखते हैं क्यों == अपने उदाहरण में लागू नहीं किया जा सकता है: ..

  • 15.21.3. Reference Equality Operators == and !=

    तो

    • 15.21.2. Boolean Equality Operators == and !=

      कोई ज़रूरत नहीं क्यों यह प्रासंगिक नहीं है उल्लेख करने के लिए एक समानता ऑपरेटर के संचालन दोनों हैं संदर्भ प्रकार या शून्य प्रकार के, तो ऑपरेशन ऑब्जेक्ट समानता है।

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

  • 15.21.1. Numerical Equality Operators == and !=

    सांख्यिक प्रकार के दोनों एक समानता ऑपरेटर की ऑपरेंड कर रहे हैं, या एक सांख्यिक प्रकार का है और अन्य परिवर्तनीय है (§5.1.8) सांख्यिक प्रकार के, बाइनरी संख्यात्मक पदोन्नति है ऑपरेंड पर प्रदर्शन (§5.6.2)।

  • अब यह मान लें कानूनी है और संकलक करने के लिए लाइन बदल:

    if (a == new Integer(b)) 
    

    क्या आप परिणाम होने की उम्मीद करते हैं? हालत true का मूल्यांकन कभी नहीं होगा, तो यह भावना है कि यह एक बग कि जावा 8.

    +19

    पर विफल रहता है हालांकि autoboxing 'Integer.valueOf' का उपयोग करके किया जाता है। चूंकि 'पूर्णांक।valueOf' कभी-कभी पूल से मान देता है, परिणाम 'सत्य' हो सकता है। – fabian

    +3

    @ फ़ैबियन तो, कभी भी सही * एक उपयोगी उपयोगी या सहज तरीके से *। – Yakk

    +2

    @MarounMaroun ठीक है, उत्तर में कोड के लिए, यह निश्चित रूप से कभी भी सच नहीं होगा। 'नया इंटीजर (बी) 'हमेशा एक वस्तु बनाता है, जबकि' Integer.valueOf (बी) 'शायद नहीं। – immibis

    5

    यह संकलित किया है नहीं करना चाहिए में तय किया गया था, JLS 7 के अनुसार है बनाता है। int की तुलना बॉक्सिंग संख्यात्मक प्रकारों, यानी बाइट, शॉर्ट, कैरेक्टर, इंटीजर, लांग, फ्लोट, डबल से की जा सकती है। लेकिन वह सब कुछ है।

    और अगर तुलना int के बीच हैं और कहते हैं Float, Float पहले unboxed किया जाएगा, ताकि तुलना float और int के बीच है। इसे अन्य तरीकों से करने का कोई मतलब नहीं होगा - बॉक्स int फिर Integer (Float कम से कम) की पहचान की जांच करें।

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