2009-12-11 27 views
5
public static void main(String [] a) 
{ 
    String s = new String("Hai"); 
    String s1=s; 
    String s2="Hai"; 
    String s3="Hai"; 
    System.out.println(s.hashCode()); 
    System.out.println(s1.hashCode()); 
    System.out.println(s2.hashCode()); 
    System.out.println(s3.hashCode()); 
    System.out.println(s==s2); 
    System.out.println(s2==s3); 

} 

ऊपर कोड से किसी को भी समझा सकता है क्या पीछे जा रहा है जब JVM इस लाइन (रों == s2) का सामना करना पड़ता?कैसे "==" वस्तुओं के लिए काम करता है?

उत्तर

17

यह तुलना संदर्भ - जो कि दोनों चर ठीक उसी वस्तु (बल्कि सिर्फ बराबर की तुलना में) की चर्चा करते हुए कर रहे हैं।

  • s और s2 विभिन्न वस्तुओं को देखें, तो अभिव्यक्ति गलत का आकलन।
  • s और s1 असाइनमेंट के कारण समान ऑब्जेक्ट्स (एक दूसरे के रूप में) देखें।
  • s2 और s3 क्योंकि स्ट्रिंग होना शामिल की (एक दूसरे के रूप में) एक ही वस्तुओं को देखें।

यदि इससे ज्यादा मदद नहीं मिलती है, तो कृपया किसी विशेष बिट पर अधिक जानकारी मांगें। वस्तुओं और संदर्भों के साथ शुरू करने में भ्रमित हो सकता है।

ध्यान दें कि केवल स्ट्रिंग शाब्दिक डिफ़ॉल्ट रूप से प्रशिक्षु कर रहे हैं ... तो भले ही s और s2 उल्लेख बराबर तार करने के लिए, वे अभी भी दो अलग-अलग वस्तुओं रहे हैं। इसी प्रकार यदि आप लिखते हैं:

String x = new String("foo"); 
String y = new String("foo"); 

तो x == y झूठे का मूल्यांकन करेगा। आप बल होना शामिल, इस मामले में वास्तव में लौट सकते हैं जो होगा प्रशिक्षु शाब्दिक:

String x = new String("foo"); 
String y = new String("foo"); 
String z = "foo"; 

// Expressions and their values: 
x == y: false 
x == z: false 
x.intern() == y.intern(): true 
x.intern() == z: true 

संपादित करें: एक टिप्पणी सुझाव दिया है कि मूल रूप से new String(String) व्यर्थ है। वास्तव में यह मामला नहीं है।

String एक ऑफसेट और लंबाई के साथ char[] को संदर्भित करता है। आप सबस्ट्रिंग लेते हैं, यह सिर्फ एक अलग ऑफसेट और लंबाई के साथ, एक नया स्ट्रिंग हीchar[] की चर्चा करते हुए पैदा करेगा। यदि आप एक लंबे समय के लिए एक लंबी स्ट्रिंग की एक छोटी-स्ट्रिंग रखने की जरूरत है, लेकिन लंबे स्वयं स्ट्रिंग की जरूरत नहीं है, तो यह उपयोगी new String(String) निर्माता का उपयोग करने के लिए सिर्फ टुकड़ा आप की जरूरत की एक प्रतिलिपि बनाने के लिए, है की अनुमति देता है संग्रहित कचरा होने के लिए बड़ा char[]

इस का एक उदाहरण एक फ़ाइल शब्दकोश पढ़ रही है - कम शब्दों के बहुत सारे, प्रति पंक्ति एक। यदि आप BufferedReader.readLine() का उपयोग करते हैं, तो आवंटित चार सरणी कम से कम 80 वर्ण (मानक जेडीके में, वैसे भी) होगी। इसका मतलब है कि "और" जैसे छोटे शब्द भी 160 बाइट्स + ओवरहेड्स की एक चार सरणी लेते हैं ... आप अंतरिक्ष से बहुत जल्दी से बाहर निकल सकते हैं। new String(reader.readLine()) का उपयोग दिन बचा सकता है।

+1

तारों को प्रशिक्षित नहीं किया गया है, तो यह वास्तव में सत्य का मूल्यांकन करता है? –

+3

@ विंस्टन स्मिथ: शाब्दिक प्रशिक्षित हैं, लेकिन 's' को कन्स्ट्रक्टर कॉल का रिटर्न वैल्यू सौंपा गया है। –

+0

@ विंस्टन: यदि वे हैं तो यह वही वस्तु होगी, लेकिन आप सवाल में इंटर्न() के लिए कहां कॉल करते हैं? – Fredrik

1

== compars एक वस्तु की सामग्री नहीं वस्तुओं। एस और एस 2 अलग-अलग वस्तुएं हैं। यदि आप सामग्री का उपयोग s.equals (एस 2) की तुलना करना चाहते हैं।

+0

अधिक विशिष्ट हो सकता है, क्योंकि मुझे पता है कि यह सामग्री की तुलना नहीं करता है। – Hariharbalaji

-3

आप स्ट्रिंग वर्ग के लिए है कुछ '==' अधिभार का उपयोग कर रहे हैं ...

+0

-1: जावा में ऑपरेटर ओवरलोडिंग नहीं है। –

+0

उम, स्ट्रिंग्स पर + को छोड़कर मुझे लगता है :-) –

0

यह एक स्पष्ट झूठी होना चाहिए। जेवीएम मेमोरी में मौजूद तारों का उपयोग करने जैसी चीज करता है। इसलिए एस 2, एस 3 उसी स्ट्रिंग को इंगित करता है जिसे एक बार तुरंत चालू किया गया है। यदि आप कुछ ऐसा करते हैं जैसे s5 = "है" तो यह एस 3 के बराबर होगा।

हालांकि नया एक नया वस्तु बनाता है। भले ही स्ट्रिंग पहले से ही exisitng या नहीं है। इसलिए एस 3, एस 4 के बराबर नहीं है।

अब अगर आप कर S6 = नया स्ट्रिंग ("हाई"), यहां तक ​​कि उस S2 के लिए, एस 3 या रों बराबर नहीं होगा।

1

मैं तुम्हें पता है कि जब आप का उपयोग कर चर के बीच समानता का परीक्षण '==', आप इस तथ्य का परीक्षण कर रहे हैं, तो स्मृति में संदर्भ ही कर रहे हैं लगता है। यह बराबर() विधि से अलग है जो एक परिणाम को वापस करने के लिए एल्गोरिदम और विशेषताओं को जोड़ता है जिसमें कहा गया है कि दो ऑब्जेक्ट्स समान मानते हैं। इस मामले में, यदि परिणाम सत्य है, तो इसका सामान्य अर्थ यह है कि दोनों संदर्भ एक ही ऑब्जेक्ट को इंगित कर रहे हैं। इससे मुझे आश्चर्य होता है कि क्यों s2 == s3 सत्य लौटाता है और क्या स्ट्रिंग इंस्टेंस (जो अपरिवर्तनीय हैं) कहीं भी पुन: उपयोग के लिए पूल किए जाते हैं।

+2

स्ट्रिंग ऑब्जेक्ट मांग पर बनाए जाते हैं। यदि एक स्ट्रिंग पहले से ही एक नई स्ट्रिंग ऑब्जेक्ट बनाने के बजाय एक ही ऑब्जेक्ट में नया संदर्भ बिंदु मौजूद है। नीचे मेरा जवाब देखें। हालांकि कथन नई स्ट्रिंग() के साथ बनाए गए ऑब्जेक्ट्स पर लागू नहीं होता है। स्पष्टीकरण के लिए – Geek

+1

धन्यवाद। तो अगर मैं ऐसा करता हूं: स्ट्रिंग s1 = नया स्ट्रिंग ("एक स्ट्रिंग"); स्ट्रिंग एस 2 = नई स्ट्रिंग ("एक स्ट्रिंग"); एस 1 और एस 2 एक ही उदाहरण के लिए बिंदु?मैं यहां मान रहा हूं कि स्ट्रिंग आवंटन बराबर है चाहे आप स्पष्ट रूप से स्ट्रिंग को तुरंत चालू करें या ऑटोबॉक्सिंग का उपयोग करें। –

+0

आह ठीक है, अब मैं समझता हूं। यदि आप एक नई स्ट्रिंग() का उपयोग करते हैं, तो आप स्पष्ट रूप से एक नए उदाहरण के निर्माण को मजबूर कर रहे हैं। यह एक तरह का मामूली बात है जिसे आप नौकरी साक्षात्कार में खींच सकते हैं। –

1
Think of it like this. 
    Identical twins look the same but they are made up differently. 
If you want to know if they "look" the same use the compare. 
If you want to know they are a clone of each other use the "==" 

:) 
1

==Object रों की स्मृति (संदर्भ) स्थान है। ऑब्जेक्ट की सामग्री की तुलना करने के लिए आपको .equals() का उपयोग करना चाहिए।

आप int और double रों के लिए == उपयोग कर सकते हैं, क्योंकि वे आदिम डेटा प्रकार के रूप में वे संकलन समय पर मौजूद हैं

0

शाब्दिक s2 और S3 स्मृति में एक ही स्ट्रिंग को इंगित करेंगे। एस रनटाइम पर बनाया गया है और स्मृति में "है" के एक अलग उदाहरण को इंगित करेगा। यदि आप एस 2 और एस 3 के रूप में "है" के एक ही उदाहरण को इंगित करना चाहते हैं तो आप इंटर्न को कॉल करके जावा के लिए ऐसा करने के लिए कह सकते हैं। तो s.intern == s2 सच होगा।

अच्छा लेख here

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