2010-09-11 11 views
10

संपादित करें: ठीक है, ठीक है, मैं गलत पढ़ता हूं। मैं इंटीजर को एक इंट की तुलना नहीं कर रहा हूं। विधिवत् नोट किया हुआ।== do के साथ इंटीग्रर्स की तुलना में वास्तव में क्या करता है?

मेरे SCJP पुस्तक का कहना है:

जब == एक आवरण के लिए एक आदिम तुलना करने के लिए प्रयोग किया जाता है, आवरण unwrapped हो जाएगा और तुलना आदिम करने के लिए आदिम हो जाएगा।

तो आपको लगता है कि हम इस कोड true प्रिंट होगा:

Integer i1 = 1; //if this were int it'd be correct and behave as the book says. 
    Integer i2 = new Integer(1); 
    System.out.println(i1 == i2); 

लेकिन यह false प्रिंट करता है।

इसके अलावा, मेरी किताब के अनुसार, इस true प्रिंट चाहिए:

Integer i1 = 1000; //it does print `true` with i1 = 1000, but not i1 = 1, and one of the answers explained why. 
Integer i2 = 1000; 
System.out.println(i1 != i2); 

नहीं। यह false है।

क्या देता है?

+0

देखें, मुझे यकीन है कि अगर किताब के इस हिस्से खराब लिखा है नहीं कर रहा हूँ या मैं कर रहा हूँ एक मूर्ख, लेकिन मैं यह नहीं कह सकता कि इसका कारण क्या है। समझने का मेरा सबसे अच्छा प्रयास यह है कि == का अलग-अलग व्यवहार किया जाता है! =। शायद == मूल्य समानता (गहरी समानता) को दर्शाता है लेकिन! = नहीं करता है। किसी भी मामले में, किताब जो कहती है वह आईआरएल नहीं होती है। –

+0

नहीं, इस मामले में समस्या दो प्रकारों में निहित है जो आप तुलना कर रहे हैं। == और! = वैसे ही व्यवहार करें। – EboMike

+0

बस यह उदाहरण मुझे यह सोचने के लिए पर्याप्त है कि जावा एक वास्तविक प्रोग्रामिंग भाषा के बजाय किसी प्रकार का बीमार मजाक है। – dsimcha

उत्तर

8
Integer i1 = 1; 
Integer i2 = new Integer(1); 
System.out.println(i1 == i2); 

जब आप आवंटित 1 i1 है कि मूल्य बॉक्सिंग है, एक Integer वस्तु का निर्माण। तुलना तब दो ऑब्जेक्ट संदर्भों की तुलना करती है। संदर्भ असमान हैं, इसलिए तुलना विफल हो जाती है।

Integer i1 = 100; 
Integer i2 = 100; 
System.out.println(i1 != i2); 

क्योंकि इन संकलन समय के साथ प्रारंभ कर रहे हैं स्थिरांक संकलक कर सकते हैं और उन्हें प्रशिक्षु करता है और एक ही Integer वस्तु को दोनों बिंदु बनाता है।

(ध्यान दें कि मैं 100 के लिए 1000 से मूल्यों को बदल @NullUserException बताते हैं के रूप में, केवल छोटे पूर्णांक प्रशिक्षु कर रहे हैं।)


यहाँ वास्तव में एक दिलचस्प परीक्षण है। देखें कि क्या आप इसे समझ सकते हैं। पहला प्रोग्राम true क्यों प्रिंट करता है, लेकिन दूसरा false? मुक्केबाजी और संकलक समय विश्लेषण के अपने ज्ञान का उपयोग करके आप में सक्षम होना चाहिए यह पता लगाने की:

// Prints "true". 
int i1 = 1; 
Integer i2 = new Integer(i1); 
System.out.println(i1 == i2); 

// Prints "false". 
int i1 = 0; 
Integer i2 = new Integer(i1); 
i1 += 1; 
System.out.println(i1 == i2); 

आप ऊपर समझते हैं, तो क्या भविष्यवाणी करने के लिए इस कार्यक्रम के प्रिंट की कोशिश:

int i1 = 0; 
i1 += 1; 
Integer i2 = new Integer(i1); 
System.out.println(i1 == i2); 

(अनुमान लगाने के बाद, run it and see!)

+0

* यह महत्वपूर्ण है क्योंकि केवल छोटे पूर्णांक इंटर्न किए जाते हैं। * - ध्यान रखें कि यह 'इंटीगर' केवल एक आंतरिक कैश को बनाए रखता है जो इसका उपयोग करता है (छोटे मूल्यों के लिए) जब 'valueOf' पर कॉल किया जाता है; कंपाइलर अभी भी 'इनोकेस्टैटिक जावा/लैंग/इंटेगर/वैल्यूएफ (आई) लाजावा/लैंग/इंटीजर की दो पंक्तियां उत्पन्न करता है; ' –

6

आप एक रैपर के लिए आदिम की तुलना नहीं कर रहे हैं। आप दो रैपर (संदर्भ प्रकार) की तुलना कर रहे हैं। == ऑब्जेक्ट पहचान की तुलना करता है, जो false देता है क्योंकि वे अलग-अलग ऑब्जेक्ट्स हैं।

0

जावा 5.0 के बाद, स्वचालित मुक्केबाजी और अनबॉक्सिंग है, जिसका अर्थ है कि रैपर को पूरी तरह से प्राइमेटिव में परिवर्तित किया जा सकता है और इसके विपरीत। हालांकि, यदि आप दो इंटीजर ऑब्जेक्ट्स की तुलना करते हैं, तो भी आप दो संदर्भों की तुलना कर रहे हैं, और ऐसा कुछ भी नहीं है जो स्वचालित मुक्केबाजी/अनबॉक्सिंग को ट्रिगर करेगा। यदि ऐसा था, तो जे 2 एसई 1.4 और पहले में लिखा गया कोड तोड़ देगा।

10

नोट जावा कैश -128 127 तक सीमा (256 मान) में Integer रों के नए संस्करण है, जिसका अर्थ यह भी है कि कि:

Integer i1, i2; 

i1 = 127; 
i2 = 127; 
System.out.println(i1 == i2); 

i1 = 128; 
i2 = 128; 
System.out.println(i1 == i2); 

true और false प्रिंट होगा। (ideone पर यह देखें)

नैतिक: समस्याओं से बचने के हमेशा .equals() का उपयोग जब दो वस्तुओं की तुलना।

जब आप == उपयोग कर रहे हैं एक आदिम करने के लिए एक आदिम लिपटे तुलना करने के लिए unboxing पर भरोसा कर सकते (जैसे: int साथ Integer), लेकिन आप == के साथ दो Integer रों तुलना कर रहे हैं कि अगर कारणों के लिए असफल हो जायेगी @ dan04 समझाया।

+0

दिलचस्प! मैं कभी भी == आईआरएल का उपयोग नहीं करता, लेकिन यह एक बहुत ही दुःखद परीक्षा है जिसके बारे में हम बात कर रहे हैं :) –

+0

वाह, यहां तक ​​कि 1.4 पहले से ही था। दिलचस्प। बहुत प्रासंगिक बिंदु के लिए – EboMike

+1

+1। मैं नाइटपिक करूँगा और इसे इंगित करूंगा [-128 से 127] (http://java.sun.com/docs/books/jls/third_edition/html/conversions.html#5.1.7), हालांकि 1.6 स्रोत जो इसके साथ आता है सूर्य जेडीके उन्हें ऊपरी बाउंड के साथ खेल खेलता है (हालांकि यह हमेशा कम से कम 127 है)। –

1

नहीं, मुझे नहीं लगता कि कोड प्रिंट सही है, और आपने स्वयं को उत्तर दिया क्यों।

जब == एक आवरण के लिए एक आदिम तुलना करने के लिए प्रयोग किया जाता है, आवरण unwrapped हो जाएगा और तुलना आदिम करने के लिए आदिम हो जाएगा।

और फिर आप दो इंटीजर संदर्भों की तुलना करने के लिए आगे बढ़े- यानी, यह i1 और i2 के स्मृति पते की तुलना में है। आप या तो

Integer i1 = 1; 
Integer i2 = new Integer(1); 
System.out.println(i1.equals(i2)); 

या

int i1 = 1; 
Integer i2 = new Integer(1); 
System.out.println(i1 == i2); 
1

ध्यान दें कि आप अंश आप उद्धृत पढ़ने में भूलना चाहता था। अंश विशेष रूप से यह बयान को सीमित करता है इस तरह की तुलना करने के लिए:

int k = 1; 
Integer l = new Integer(1); 
System.out.println(l == k); 
0

मान लीजिए देना एक उदाहरण

क्या इस कार्यक्रम कोड के उत्पादन होगा है?

public class autoboxing { 
public static void main(String a args) { 
Integer a = new Integer(127); 
Integer b = new Integer(127); 
Integer c = 127; 
Integer d = 127; 
Integer e = new Integer(200); 
Integer f = new Integer(200); 
Integer g = 200; 
Integer h = 200; 
System.out.println((a == b) + ' " + (c =-- d) + " " + (e==f)+ " "+ (g == h)); 

जब आप किसी नए ऑपरेटर के साथ एक इंटेगर ऑब्जेक्ट बनाते हैं, तो यह हर बार एक नई वस्तु देता है। जब आप दो संदर्भ चर के साथ "==" ऑपरेटर की तुलना कर रहे हैं, यदि दो संदर्भ चर दो अलग-अलग ऑब्जेक्ट्स का जिक्र कर रहे हैं, तो "==" ऑपरेटर झूठा रिटर्न देता है।

तो,

(एक == ख) और (ई == च) भाव झूठी देता है। इंटीजर क्लास कैश -128 से 127 के बीच कैश मानता है।

जब आप दो इंटीजर ऑब्जेक्ट्स की तुलना "==" ऑपरेटर के साथ करते हैं, तो उन दो पूर्णांक ऑब्जेक्ट्स को ऑटोबॉक्सिंग के साथ बनाया जाता है तो value0f (int i) विधि को कॉल किया जाएगा।

उत्तर: गलत सच झूठी झूठी

नीचे है कि विधि के क्रियान्वयन

public static Integer value0f(int i) { 
if (i >= IntegerCachedow && i <= IntegerCache.high) 
return IntegerCache.cacheli + (-IntegerCachedow)); 
return new Integer(i); 

उपरोक्त क्रियान्वयन से है, नीचे दिए गए निष्कर्ष

  1. तो दो पूर्णांक वस्तुओं रहे हैं मान -128 से 127 के बीच हैं, यह विधि समान मान देता है। तो (सी == डी) सच लौटाता है।

  2. यदि दो इंटीजर ऑब्जेक्ट मान श्रेणी के बाहर हैं -128 से 127, यह विधि विभिन्न नई पूर्णांक ऑब्जेक्ट्स लौटाती है। तो, (छ == ज) विधि के बारे में यहाँ रिटर्न झूठी

अधिक विस्तार: https://stackoverflow.com/questions/20897020/why-integer-class-caching-values-in-the-range-128-to-127