2012-01-19 14 views
5

String रों जावा में अपरिवर्तनीय हैं, तो हम कैसे के रूप में लिख सकते हैं:जावा अपरिवर्तनीय तार भ्रम

String s = new String(); 
s = s + "abc"; 
+2

क्योंकि 's'' अंतिम' नहीं है। – SLaks

+1

एस स्ट्रिंग नहीं है, यह एक कंटेनर है जो एक स्ट्रिंग का संदर्भ रखता है। सबसे पहले, यह नई स्ट्रिंग() द्वारा लौटाई गई स्ट्रिंग का संदर्भ रखता है, फिर इसे स्ट्रिंग का संदर्भ रखने के लिए बदला जाता है जो नई स्ट्रिंग() + "एबीसी" यानी दूसरी स्ट्रिंग के संदर्भ में लौटाया जाता है। – ignis

उत्तर

7

आपकी स्ट्रिंग चर स्ट्रिंग नहीं है। यह स्ट्रिंग के एक उदाहरण के लिए एक संदर्भ है।

खुद के लिए देखें:

String str = "Test String"; 
System.out.println(System.identityHashCode(str)); // INSTANCE ID of the string 

str = str + "Another value"; 
System.out.println(System.identityHashCode(str)); // Whoa, it's a different string! 

उदाहरणों str चर अंक को व्यक्तिगत रूप से अपरिवर्तनीय हैं, लेकिन चर आप चाहते हैं स्ट्रिंग के किसी भी मामले की ओर इशारा किया जा सकता है।

आप एक अलग स्ट्रिंग उदाहरण को इंगित करने के str पुन: असाइन करने के लिए यह संभव होने के लिए नहीं करना चाहते हैं, यह अंतिम घोषित:

final String str = "Test String"; 
System.out.println(System.identityHashCode(str)); // INSTANCE ID of the string 

str = str + "Another value"; // BREAKS HORRIBLY 
+0

'स्ट्रिंग की ऑब्जेक्ट' को कास्ट करने का क्या मतलब है? – Natix

+0

सरल। str.toString() देता है ... स्ट्रिंग। कॉलिंग (ऑब्जेक्ट) str) .toString() हमें वास्तविक इंस्टेंस आईडी देता है। यह प्रदर्शन उद्देश्यों के लिए है। –

+2

नहीं, ऐसा नहीं है। जावा में तरीके वर्चुअल हैं, किसी ऑब्जेक्ट को सुपर टाइप पर कास्टिंग करने का कोई प्रभाव नहीं पड़ता है। 'स्ट्रिंग' ओवरड्रिन 'toString()' विधि कार्यान्वयन अभी भी कहा जाएगा। ऑब्जेक्ट की मूल पहचान आधारित हैशकोड प्राप्त करने के लिए आपको 'System.identityHashCode (str)' को कॉल करने की आवश्यकता है। – Natix

8

स्ट्रिंग्स अपरिवर्तनीय हैं।
इसका मतलब है कि उदाहरणString बदल नहीं सकता है।

आप एक अलग (लेकिन अभी भी अडिग) String उदाहरण का उल्लेख करने के sचर बदल रहे हैं।

0
String s = new String(); 

एक नया, अपरिवर्तनीय, खाली स्ट्रिंग, परिवर्तनीय "संदर्भ" बनाता है।

s = s+"abc";    

एक नया, अपरिवर्तनीय, स्ट्रिंग बनाता है; खाली स्ट्रिंग और "एबीसी" का संगतता, चर "एस" अब इस नई वस्तु का संदर्भ देता है।

Foo f = new Foo("a"); 
f.setField("b"); // Now, you are changing the field of class Foo 

लेकिन अपरिवर्तनीय कक्षाएं, उदा:

1

अपरिवर्तनीय वर्ग जिनकी तरीकों उदाहरण के लिए अपने खेतों को बदल सकते हैं, कर रहे हैं स्ट्रिंग, आप इसे बनाने के बाद ऑब्जेक्ट को नहीं बदल सकते हैं, लेकिन बेशक, आप किसी अन्य ऑब्जेक्ट के संदर्भ को पुन: असाइन कर सकते हैं। उदाहरण के लिए:

String s = "Hello"; 
s.substring(0,1); // s is still "Hello" 
s = s.substring(0,1); // s is now referring to another object whose value is "H" 
0

बस स्पष्ट करने के लिए, जब आप एस = एस + "एबीसी" कहते हैं; इसका मतलब है, एक नया स्ट्रिंग इंस्टेंस बनाएं (जो एस और "एबीसी" से बना है) फिर उस नए स्ट्रिंग इंस्टेंस को एस को असाइन करें। तो एस में नया संदर्भ पुराने से अलग है।

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

2

पहला उत्तर बिल्कुल सही है। आपको इसे उत्तर के रूप में चिह्नित करना चाहिए।

s = s+"abc" एस ऑब्जेक्ट में शामिल नहीं है। यह एक नई स्ट्रिंग बनाता है जिसमें ऑब्जेक्ट के वर्ण होते हैं (जिनमें से कोई नहीं है) और "एबीसी"।

यदि स्ट्रिंग उत्परिवर्तनीय थे। इसमें स्ट्रिंगबिल्डर और स्ट्रिंगबफर पर एपेंड() और ऐसी अन्य उत्परिवर्तनीय विधियां जैसी विधियां होंगी।

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

0
String s = new String(); 

एक खाली String वस्तु ("") बनाया जाता है। और चर s उस वस्तु को संदर्भित करता है।

s = s + "abc"; 

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

तो, s + "abc" के इस बिंदु संयोजन और रिक्त स्ट्रिंग ("") और "abc" पर के बाद से वास्तव में एक नया String वस्तु का निर्माण नहीं करता क्योंकि अंतिम परिणाम "abc" जो पूल में पहले से ही है। तो, अंततः परिवर्तनीय s पूल में शाब्दिक "abc" का संदर्भ लेंगे।

-2

मेरा मानना ​​है कि आप इसे सब कुछ अधिक जटिल बना रहे हैं, और यह केवल उन लोगों को भ्रमित कर रहा है जो सीखने की कोशिश कर रहे हैं!

एक वस्तु जावा में अपरिवर्तनीय बनाने के प्राथमिक लाभ यह है कि यह नीचे की ओर के बारे में चिंता किए बिना संदर्भ द्वारा पारित किया जा सकता (किसी अन्य विधि के लिए उदाहरण के लिए या असाइनमेंट ऑपरेटर का उपयोग कर सौंपा) वस्तु को में परिवर्तन में समस्या आ रही है वर्तमान विधि या संदर्भ। (यह किसी ऑब्जेक्ट की थ्रेड सुरक्षा के बारे में किसी भी वार्तालाप से बहुत अलग है।)

उदाहरण के लिए, एक स्ट्रिंग को एक अलग विधि के पैरामीटर के रूप में पास करने वाला एक एप्लिकेशन बनाएं, और उस विधि में स्ट्रिंग को संशोधित करें। बुलाए गए विधि के अंत में स्ट्रिंग प्रिंट करें और फिर नियंत्रण के बाद कॉलिंग विधि पर वापस आ जाए। स्ट्रिंग्स के पास अलग-अलग मान होंगे, और ऐसा इसलिए है क्योंकि वे अलग-अलग मेमोरी स्थानों को इंगित करते हैं, अपरिवर्तनीय स्ट्रिंग को "बदलना" का प्रत्यक्ष परिणाम (एक नया पॉइंटर बनाना और इसे दृश्यों के पीछे एक नए मान पर इंगित करना)। फिर एक ऐसा एप्लिकेशन बनाएं जो स्ट्रिंगबफर को छोड़कर वही काम करता है, जो अपरिवर्तनीय नहीं है। (उदाहरण के लिए, आप इसे संशोधित करने के लिए स्ट्रिंगबफर में जोड़ सकते हैं।) मुद्रित स्ट्रिंगबफर के पास समान मान होंगे, और ऐसा इसलिए है क्योंकि यह (ए) संदर्भ द्वारा पारित किया जा रहा है, क्योंकि जावा पैरामीटर के रूप में विधियों के लिए पारित सभी वस्तुओं के साथ करता है और (बी) उत्परिवर्तनीय।

मुझे आशा है कि यह उन लोगों की मदद करेगा जो इस धागे को पढ़ रहे हैं और सीखने की कोशिश कर रहे हैं!

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