2009-11-09 10 views
120
class D { 
    public static void main(String args[]) { 
     Integer b2=128; 
     Integer b3=128; 
     System.out.println(b2==b3); 
    } 
} 

आउटपुट:128 == 128 झूठी वापसी क्यों करता है लेकिन 127 == 127 इंटीजर रैपर में कनवर्ट करते समय सत्य वापस आते हैं?

false 

class D { 
    public static void main(String args[]) { 
     Integer b2=127; 
     Integer b3=127; 
     System.out.println(b2==b3); 
    } 
} 

आउटपुट:

true 

नोट: -128 और 127 के बीच की संख्याओं सही हैं।

+10

आप http://bexhuff.com/2006/11/java-1-5-autoboxing-wackyness जानकारीपूर्ण मिल सकती है। –

+1

इस सवाल से पूछने के लिए आप कैसे गए थे? यह वास्तव में मजेदार है, लेकिन कोई भी "वास्तविक दुनिया में" जैसे किसी चीज़ पर कभी नहीं आता है ... या? –

+0

http://stackoverflow.com/a/11882284/57695 –

उत्तर

167

जब आप एक नंबर जावा में शाब्दिक संकलन और एक पूर्णांक (राजधानी I) संकलक का उत्सर्जन करता है के लिए असाइन करें:

Integer b2 =Integer.valueOf(127) 

कोड की यह पंक्ति भी उत्पन्न होता है जब आप autoboxing का उपयोग करें।

valueOf ऐसी है कि कुछ संख्या "जमा" कर रहे हैं कार्यान्वित किया जाता है, और यह की तुलना में 128

जावा 1.6 स्रोत कोड से छोटे मूल्यों के लिए एक ही उदाहरण देता है, लाइन 621:

public static Integer valueOf(int i) { 
    if(i >= -128 && i <= IntegerCache.high) 
     return IntegerCache.cache[i + 128]; 
    else 
     return new Integer(i); 
} 

high का मान सिस्टम प्रॉपर्टी के साथ किसी अन्य मान पर कॉन्फ़िगर किया जा सकता है।

-Djava.lang.Integer.IntegerCache.high = 999

आपको लगता है कि प्रणाली संपत्ति के साथ अपने कार्यक्रम चलाते हैं, यह उत्पादन सच होगा!

स्पष्ट निष्कर्ष: दो संदर्भों पर समान भरोसा न करें, हमेशा .equals() विधि से उनकी तुलना करें।

तो b2.equals(b3) बी 2, बी 3 के सभी तर्कसंगत बराबर मानों के लिए सच प्रिंट करेगा।

ध्यान दें कि इंटीजर कैश प्रदर्शन कारणों से नहीं है, बल्कि JLS, section 5.1.7 के अनुरूप है; ऑब्जेक्ट पहचान मानों के लिए -128 से 127 समावेशी के लिए दी जानी चाहिए।

Integer#valueOf(int) भी इस व्यवहार दस्तावेजों:

इस विधि अक्सर अनुरोध किया मूल्यों कैशिंग द्वारा काफी बेहतर स्थान और समय प्रदर्शन उपज की संभावना है। इस विधि हमेशा रेंज -128 को 127, समावेशी में मूल्यों कैश जाएगा, और इस सीमा के बाहर अन्य मूल्यों को संचित कर सकता।

+1

ध्यान दें कि 127 से छोटे मान जावा द्वारा अनदेखा किए जाएंगे और Integer.MAX_VALUE-128 से बड़े मानों को कैप्चर किया जाएगा। –

+0

इंटीजर जावा 5 और उच्चतर में बाइट मानों के लिए कैश किए जाते हैं, जिससे नया इंटीजर (1) == नया इंटीजर (1) बना रहता है। हालांकि, यह जावा 1.4 या उससे कम का मामला नहीं है, इसलिए सावधान रहें यदि आपको अंततः उस पर्यावरण में डाउनग्रेड करना है। – MetroidFan2002

+10

नहीं, यह गलत है। नया इंटीजर (1) == नया इंटीजर (1) जेवीएम की परवाह किए बिना गलत है। AFAIK कोई कंपाइलर "नया" कीवर्ड पर धोखा देगा। यह हमेशा एक नई वस्तु को तत्काल करना चाहिए। –

19

ऑटोबॉक्सिंग कैश -128 से 127. यह जेएलएस (5.1.7) में निर्दिष्ट है।

यदि मान पी बॉक्सिंग किया जा रहा सच है, गलत है, एक बाइट, रेंज \ u0000 में एक चार को \ u007f, या एक पूर्णांक या -128 और 127 के बीच कम संख्या है, तो r1 जाने और आर 2 पी के किसी भी दो मुक्केबाजी रूपांतरण के परिणाम हो। यह हमेशा मामला है कि आर 1 == आर 2।

एक साधारण नियम याद करने के लिए वस्तुओं के साथ काम कर रहा है जब - उपयोग .equals आप अगर दो वस्तुओं "समान" हैं जाँच करना चाहते हैं, उपयोग == जब आप को देखने के लिए अगर वे एक ही उदाहरण को इंगित चाहते ।

8

आदिम डेटा प्रकारों, इन्ट्स का उपयोग, दोनों मामलों में अपेक्षित आउटपुट में सही साबित होगा।

हालांकि, अगर आप पूर्णांक का उपयोग कर रहे के बाद से वस्तुओं == ऑपरेटर एक अलग अर्थ है।

वस्तुओं के संदर्भ में, चेकों == करने के लिए यदि चर एक ही वस्तु संदर्भ देखें देखें।

वस्तुओं के मूल्य की तुलना करने के लिए आप बराबर() विधि जैसे का उपयोग करना चाहिए

b2.equals(b1) 

जो इंगित करेगा कि क्या b2 करने के लिए बी 1 की तुलना में कम, अधिक से अधिक, या उसके बराबर है (विवरण के लिए एपीआई जांच)

-4

मैं इस समस्या सिर्फ पूर्णांक के लिए विशिष्ट नहीं है निम्नलिखित लिखा था। मेरा निष्कर्ष है कि अधिक बार नहीं है, तो आप एपीआई गलत तरीके से उपयोग करते हैं, आप चौखट गलत व्यवहार देखते हैं। इसे सही ढंग से उपयोग करें और आप सही व्यवहार देखना चाहिए:

public static void main (String[] args) { 
    Byte b1=127; 
    Byte b2=127; 

    Short s1=127; //incorrect should use Byte 
    Short s2=127; //incorrect should use Byte 
    Short s3=128; 
    Short s4=128; 

    Integer i1=127; //incorrect should use Byte 
    Integer i2=127; //incorrect should use Byte 
    Integer i3=128; 
    Integer i4=128; 

    Integer i5=32767; //incorrect should use Short 
    Integer i6=32767; //incorrect should use Short 

    Long l1=127L;   //incorrect should use Byte 
    Long l2=127L;   //incorrect should use Byte 
    Long l3=13267L;   //incorrect should use Short 
    Long l4=32767L;   //incorrect should use Short 
    Long l5=2147483647L; //incorrect should use Integer 
    Long l6=2147483647L; //incorrect should use Integer 
    Long l7=2147483648L; 
    Long l8=2147483648L; 

    System.out.print(b1==b2); //true (incorrect) Used API correctly 
    System.out.print(s1==s2); //true (incorrect) Used API incorrectly 
    System.out.print(i1==i2); //true (incorrect) Used API incorrectly 
    System.out.print(l1==l2); //true (incorrect) Used API incorrectly 

    System.out.print(s3==s4); //false (correct) Used API correctly 
    System.out.print(i3==i4); //false (correct) Used API correctly 
    System.out.print(i5==i6); //false (correct) Used API correctly 
    System.out.print(l3==l4); //false (correct) Used API correctly 
    System.out.print(l7==l8); //false (correct) Used API correctly 
    System.out.print(l5==l6); //false (correct) Used API incorrectly 

} 
2

, Integer.java पर एक नज़र डालें, तो मूल्य -128 और 127 के बीच है, यह, कैश्ड पूल का उपयोग करेगा तो (Integer) 1 == (Integer) 1 जबकि (Integer) 222 != (Integer) 222

/** 
* Returns an {@code Integer} instance representing the specified 
* {@code int} value. If a new {@code Integer} instance is not 
* required, this method should generally be used in preference to 
* the constructor {@link #Integer(int)}, as this method is likely 
* to yield significantly better space and time performance by 
* caching frequently requested values. 
* 
* This method will always cache values in the range -128 to 127, 
* inclusive, and may cache other values outside of this range. 
* 
* @param i an {@code int} value. 
* @return an {@code Integer} instance representing {@code i}. 
* @since 1.5 
*/ 
public static Integer valueOf(int i) { 
    assert IntegerCache.high >= 127; 
    if (i >= IntegerCache.low && i <= IntegerCache.high) 
     return IntegerCache.cache[i + (-IntegerCache.low)]; 
    return new Integer(i); 
}  
4

यह संबंधित जावा में स्मृति अनुकूलन है।

स्मृति पर बचाने के लिए, जावा 'reuses' सभी आवरण वस्तुओं जिसका मान निम्न श्रेणियों में गिरावट:

सभी बूलियन मान (सही और गलत)

सभी बाइट मूल्यों

\ u0000 से

सभी चरित्र मूल्यों \ u007f करने (यानी 0 दशमलव में 127 तक)

सभी लघु और पूर्णांक -128 से 127 तक मान।

नोट:

  • आप नए बूलियन (मान) के साथ बूलियन बनाते हैं; आपको हमेशा नई ऑब्जेक्ट

  • यदि आप नई स्ट्रिंग (मान) के साथ स्ट्रिंग बनाते हैं; आपको हमेशा नई ऑब्जेक्ट

  • यदि आप नए इंटीजर (मान) के साथ पूर्णांक बनाते हैं; तुम हमेशा मिल जाएगा नई वस्तु

आदि

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