2015-11-24 11 views
6

मैं कोड के दो टुकड़े तुलना कर रहा हूंजावा - मुक्केबाजी पूर्णांक - क्यों यह सच लौट यदि झूठे लौट जाना

Integer x = new Integer(0), y; 
y=x; 
x+=0; 
System.out.println(x==y); // prints false 

और

Integer x = 0, y; 
y=x; 
x+=0; 
System.out.println(x==y); // prints true 

दोनों वापस नहीं चाहिए false? यह शून्य जोड़ने के बाद भी प्राथमिक कोड नहीं है और किसी भी तरह दूसरे कोड में, यह true प्रिंट करता है। मुझे मुक्केबाजी के बारे में पता है (128 से 127 तक इंटीजर के लिए) लेकिन फिर मुक्केबाजी कोड के दूसरे भाग में क्यों काम करती है, न कि पहले पर?

+1

नहीं, क्योंकि '-128 - 127' की सीमा में 'इंटीजर' कैश हो रही है। आपके पहले उदाहरण में आप एक नया 'इंटेगर' बनाने की व्याख्या कर रहे हैं, इस तथ्य के बावजूद कि '-128 - 127' की सीमा में प्रत्येक 'इंटीजर' एक ही ऑब्जेक्ट को संदर्भित करेगा। – SomeJavaGuy

+0

अन्य उत्तरों के बावजूद -128 - 127 मतभेद नहीं है, यह सिर्फ जेवीएम की एक विशेषता है, जिसे '-Djava.lang.Integer.IntegerCache.high' संपत्ति' के साथ कुछ संस्करणों पर tweaked किया जा सकता है, और डिफ़ॉल्ट मान नाटकीय रूप से भिन्न हो सकते हैं JVM के लिए JVM, ** आपको इस व्यवहार पर कभी भरोसा नहीं करना चाहिए! ** http: // stackoverflow देखें।कॉम/प्रश्न/15052216/कैसे-बड़े-द-द-इंटीजर-कैश –

उत्तर

16

दोनों झूठी वापसी नहीं करनी चाहिए?

लाइन

x += 0; 

रूप

x = Integer.valueOf(x.intValue() + 0); 

में ही है, तो आप इसे आपरेशन पूरा करने के लिए बॉक्सिंग और unboxing का उपयोग करता है देखते हैं।


दूसरा उदाहरण केवल मुक्केबाजी का उपयोग करता है, इसलिए यह अपेक्षा के अनुसार काम करता है।

पहले उदाहरण में, आप स्पष्ट रूप से

Integer x = new Integer(0); 

साथ मुक्केबाजी से बचने यह मजबूर करता है कि यह एक नई वस्तु जो बॉक्स्ड वस्तु के लिए अलग है बनाने के लिए।

आप

Integer x = Integer.valueOf(0); 

करते हैं यह दूसरा उदाहरण के रूप में ही व्यवहार करेगा।

+0

शायद यदि संकलक पर्याप्त स्मार्ट था, तो शायद यह '0' से वृद्धि को अनदेखा कर सकता था? – TheLostMind

+0

@ विनोद मद्यल्कर हां, हालांकि इसका एक दुष्प्रभाव है। जावा संगतता तोड़ने के लिए बहुत अनिच्छुक है भले ही यह आईएमएचओ को ज्यादा समझ में न आए। नोट: 'x + = 0f' कुछ मूल्यों के लिए कुछ आश्चर्यजनक रूप से कुछ करता है। –

+0

मैंने वास्तव में टिप्पणी करने से पहले इसके बारे में सोचा था। लेकिन निश्चित रूप से संकलक सामान्य मामलों में चीजें कर सकते हैं (जैसे प्रश्न में) :)। यह शायद कई बाइटकोड निर्देशों को रोक देगा – TheLostMind

5

नहीं, क्योंकि -128 - 127 की सीमा में पूर्णांक कैश हो रहा है। आपके पहले उदाहरण में आप एक नया इंटीजर बनाने की व्याख्या कर रहे हैं, इस तथ्य के बावजूद कि -128 - 127 की सीमा में प्रत्येक इंटीजर एक ही ऑब्जेक्ट को संदर्भित करेगा।

यदि आप अपने पहले उदाहरण में कुछ जोड़ते हैं तो आप इसे सूचित कर सकते हैं। सूचित करें कि यह केवल -128 - 127

Integer x = new Integer(0), y; 
Integer z = 0; // refers to the cached value. 
y=x; 
x+=0; 
System.out.println(x==z); // This will now print true, since x+=0 will return the cached Integer. 

की Integer रेंज में काम करेंगे आपका दूसरे उदाहरण अभ्यस्त उदाहरण के लिए अगर आप कुछ अलग करने के लिए मूल्य x बदल जाएगा अच्छी तरह से अब काम, 360

1

वजह से,

इंटीजर एक्स एक वस्तु है। तो ==, तुलना संदर्भ और मूल्य नहीं है।

पूर्णांक एक्स, एक वस्तु तो == नहीं है मूल्य

आपका सरल कोड तुलना:

Integer x = new Integer(0), y; 
y=x; 
x+=0; 
System.out.println(x==y); // prints false 
System.out.println(x.equals(y)); // prints true 

int x1, y1; 
x1 = 5; 
y1 = x1; 

System.out.println(x1==y1); // prints true 
System.out.println(((Integer) x1).equals(y1)); //prints true 

और परिणाम:

  • झूठी
  • सच
  • सच
  • सच

सादर

ठीक है - मैं javap साथ प्रतिक्रिया (कि उत्तर के लिए धन्यवाद) देखा है और मैं समझता हूँ कि मैं क्या याद आती है। हालांकि, मुझे लगता है कि कोड का टुकड़ा दिलचस्प है।

+1

मुझे लगता है कि आपको प्रश्नकर्ता के प्रश्न का सार नहीं मिला। वह हैरान है, दूसरा उदाहरण सच क्यों लौटता है। – Michal

3

[अद्यतन]new Integer(int) का उपयोग करना हमेशा एक नई वस्तु में परिणाम की Integer.valueOf(int) मूल्यों का संचय हो पाता है जबकि संकलक, वर्ग पुस्तकालय, या JVM द्वारा किया जाना गारंटी है।

व्याख्या करने के लिए मैंने कोड नीचे लिखा है और javap उपकरण का उपयोग किया है, नीचे कोड उत्पन्न करने के लिए आदेश मैंने javap -c <Classname> का उपयोग किया है जो आपको बाइट कोड देता है।

Integer x = new Integer(0), y; 
    y=x; 
    x+=0; 
    System.out.println(x==y); // prints false 

enter image description here

आप उपरोक्त कोड में देखेंगे अगर यह गतिशील स्मृति allocator जो new है साथ नई वस्तु बनाता है। अब नीचे के रूप में दूसरे मामले में:

Integer x = 0, y; 
    y=x; 
    x+=0; 
    System.out.println(x==y); // prints true 

enter image description here

पीटर के कहे अनुसार यह valueOf विधि है जिसका अर्थ है कि यह रन समय में एक ही वस्तु तुलना कर रहा है तो यह वस्तु तुलना ऑपरेटर (==) के साथ true वापस आ जाएगी उपयोग करता है।

enter image description here

मुझे आशा है कि इस मदद करता है: लेकिन पहले मामले में यह नई वस्तु है जिसके नीचे डिबगिंग स्नैपशॉट में विशिष्ट है बनाने था। :)

जिस तरह से केविन एशे उत्तर भी सवाल में जोड़ता है। चूंकि यह मूल रूप से कैश किए गए ऑब्जेक्ट का संदर्भ दे रहा है, String के मामले में इसे जोड़ने का प्रयास करें। यदि आप new String("some_string") का उपयोग कर रहे हैं तो यह उपलब्ध होने पर नई ऑब्जेक्ट अन्य बना देगा, यह string pool से उपयोग करेगा। और याद रखें कि आप रैपर वर्गों का उपयोग आदिम नहीं कर रहे हैं।

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