स्ट्रिंग जावा में अपरिवर्तनीय क्यों है?


177

मुझे एक साक्षात्कार में पूछा गया था कि स्ट्रिंग अपरिवर्तनीय क्यों है

मैंने इस तरह उत्तर दिया:

जब हम जावा में एक स्ट्रिंग बनाते हैं, String s1="hello";तो एक वस्तु को स्ट्रिंग पूल (हैलो) में बनाया जाएगा और s1 को हैलो के लिए इंगित किया जाएगा। यदि हम फिर से करते हैं, String s2="hello";तो दूसरी वस्तु नहीं बनाई जाएगी, लेकिन s2 इंगित करेगा hello क्योंकि JVM पहले जांच करेगा। यदि एक ही वस्तु स्ट्रिंग पूल में मौजूद है या नहीं। यदि मौजूद नहीं है तो केवल एक नया बनाया जाता है और नहीं।

अब अगर मान लीजिये कि java स्ट्रिंग को बदलने योग्य बनाता है तो यदि हम s1 को बदलते हैं hello worldतो s2 मान भी होगा hello worldइसलिए java स्ट्रिंग अपरिवर्तनीय है।

क्या कोई शरीर मुझे बता सकता है कि मेरा उत्तर सही है या गलत ?


46
क्यों हमेशा जवाब देना मुश्किल है। सबसे सही उत्तर शायद यह है: क्योंकि भाषा डिजाइनरों ने सोचा कि यह एक अच्छा विचार था।
केपील

1
यह भी देखें, यह उत्तर

3
आपका उत्तर बिंदु पर नहीं है। सी ++ std::stringपरस्पर है, लेकिन उनके पास स्ट्रिंग पूल के साथ-साथ (अच्छी तरह से, अधिक सही ढंग से, चरित्र सरणी पूल) है।
सियुआन रेन

1
@ पारंगत होना, चाहे वह सही हो या न हो, इस पर निर्भर करता है कि वे इसे कैसे पढ़ते हैं। बात यह है, जावा में एक स्ट्रिंग पूल हो सकता है क्योंकि तार अपरिवर्तनीय हैं। यदि वे तार को परस्पर जोड़ने का निर्णय लेते हैं, तो वे एक स्ट्रिंग पूल का उपयोग नहीं करेंगे; इसलिए "स्ट्रिंग पूल, इसलिए अपरिवर्तनीय तार" कहना सही नहीं होगा; यह अन्य तरह से चारों ओर है। कारणों अपरिवर्तनीय तार को चुनने के लिए नीचे दिये हैं, और स्ट्रिंग पूल एक काम कर रणनीति है क्योंकि इस बात का। फिर भी, आपका जवाब गलत नहीं है , यह सिर्फ पूरा नहीं लगता है। आपको बस इंतजार करना होगा और देखना होगा कि वे क्या कहते हैं।
जेसन सी

34
मैं बस समझ नहीं पा रहा हूं कि यह सवाल क्यों बंद किया गया। संबंधित संबंधित उत्तर भी जावा के बारे में नहीं है और इस प्रश्न के मुख्य विषय को संबोधित नहीं करता है, जो "क्यों" है। मेरे लिए यह एक गैर-जिम्मेदार समुदाय के उन मामलों में से एक है, जिनके बारे में कोई सवाल नहीं है। मैंने इसे फिर से खोलने के लिए नामांकित किया है।
एडविन दलेरजो

जवाबों:


163

String कई कारणों से अपरिवर्तनीय है, यहाँ एक सारांश है:

  • सुरक्षा : मापदंडों को आमतौर पर Stringनेटवर्क कनेक्शन, डेटाबेस कनेक्शन यूआरएल, उपयोगकर्ता नाम / पासवर्ड आदि के रूप में दर्शाया जाता है। यदि यह परिवर्तनशील थे, तो इन मापदंडों को आसानी से बदला जा सकता है।
  • सिंक्रोनाइज़ेशन और कंसिस्ट्रेशन: स्ट्रिंग को अपरिवर्तनीय बनाने से स्वचालित रूप से उन्हें थ्रेड सुरक्षित हो जाता है जिससे सिंक्रोनाइज़ेशन समस्याएँ हल हो जाती हैं।
  • कैशिंग : जब कंपाइलर आपके स्ट्रिंग ऑब्जेक्ट्स का अनुकूलन करता है, तो यह देखता है कि यदि दो वस्तुओं का एक ही मूल्य (a = "परीक्षण", और b = "परीक्षण") है और इस प्रकार आपको केवल एक स्ट्रिंग ऑब्जेक्ट (दोनों a और b के लिए, इन दोनों की आवश्यकता होगी उसी वस्तु की ओर इशारा)।
  • क्लास लोडिंग : क्लास लोडिंग केString लिए तर्क के रूप में उपयोग किया जाता है। यदि उत्परिवर्तनीय है, तो यह गलत कक्षा में लोड हो सकता है (क्योंकि उत्परिवर्तनीय वस्तुएं उनके राज्य को बदल देती हैं)।

कहा जा रहा है, Stringकेवल अपरिवर्तनीयता का अर्थ है कि आप इसे अपने सार्वजनिक API का उपयोग करके बदल नहीं सकते। आप वास्तव में प्रतिबिंब का उपयोग करके सामान्य एपीआई को बायपास कर सकते हैं। इसका जवाब यहां देखें ।

आपके उदाहरण में, यदि Stringवह परिवर्तनशील था, तो निम्नलिखित उदाहरण पर विचार करें:

  String a="stack";
  System.out.println(a);//prints stack
  a.setValue("overflow");
  System.out.println(a);//if mutable it would print overflow

14
यह सुरक्षा को कैसे प्रभावित कर सकता है?
अर्चित माहेश्वरी

2
यदि संभव हो तो कोई उदाहरण के साथ कक्षा लोडिंग की व्याख्या कर सकता है?
विराज

6
सुरक्षा के संबंध में, यदि मैं कनेक्शन पैरामीटर बदलने में दिलचस्पी रखता हूं, तो यह रन-टाइम (डिबगर आदि के साथ) पर सीधा है। वर्ग लोडिंग के बारे में, यदि Stringयह परिवर्तनशील है, तो कक्षा लोडर में पारित स्ट्रिंग को ले जाएगा, एक प्रतिलिपि बनाएँ, और इसकी प्रतिलिपि को न बदलें। जब उत्परिवर्ती java.lang.Strings के साथ एक समस्या के बारे में सोचें, तो सोचें कि C ++ इस समस्या को कैसे हल करता है (क्योंकि इसमें उत्परिवर्ती std::strings है।
सीमित प्रायश्चित

सुरक्षा के बारे में, जब प्रोग्राम चल रहा हो तो एक परिवर्तनशील स्ट्रिंग को कैसे बदला जा सकता है?
मास्टरजॉ 2

चूंकि स्ट्रिंग अपरिवर्तनीय है, इसके हैशकोड को निर्माण के समय कैश किया गया है और इसे फिर से गणना करने की आवश्यकता नहीं है।
अब्दुल अलीम शाकिर

45

जावा डेवलपर तय करते हैं कि निम्नलिखित पहलू डिजाइन, दक्षता और सुरक्षा के कारण स्ट्रिंग्स अपरिवर्तनीय हैं ।

डिज़ाइन स्ट्रिंग्स को एक विशेष मेमोरी क्षेत्र में जावा हीप में बनाया जाता है जिसे "स्ट्रिंग इंटर्न पूल" के रूप में जाना जाता है। जब आप नया स्ट्रिंग बनाते हैं (स्ट्रिंग () कंस्ट्रक्टर का उपयोग करने के मामले में नहीं) या किसी अन्य स्ट्रिंग फ़ंक्शन का उपयोग करते हैं जो आंतरिक रूप से स्ट्रिंग () कंस्ट्रक्टर का उपयोग एक नई स्ट्रिंग ऑब्जेक्ट बनाने के लिए करते हैं; स्ट्रिंग () कंस्ट्रक्टर हमेशा पूल में नए स्ट्रिंग स्थिरांक बनाते हैं जब तक हम नहीं करते; विधि इंटर्न () ) चर को कॉल करें यह जाँच करता है कि पूल पहले से मौजूद है या नहीं। यदि यह मौजूद है, तो मौजूदा स्ट्रिंग ऑब्जेक्ट का संदर्भ लौटाएं। यदि स्ट्रिंग अपरिवर्तनीय नहीं है, तो स्ट्रिंग को एक संदर्भ के साथ बदलने से अन्य संदर्भों के लिए गलत मान हो जाएगा।

DZone पर इस लेख के अनुसार :

सुरक्षा स्ट्रिंग को व्यापक रूप से कई जावा कक्षाओं के लिए पैरामीटर के रूप में उपयोग किया जाता है, जैसे नेटवर्क कनेक्शन, फाइलें खोलना, आदि अपरिवर्तनीय नहीं थे, एक कनेक्शन या फ़ाइल को बदल दिया जाएगा और गंभीर सुरक्षा खतरे को जन्म देगा। परावर्तनों में परस्पर तार सुरक्षा समस्या का कारण बन सकते हैं, क्योंकि पैरामीटर तार होते हैं।

दक्षता जावा में स्ट्रिंग का हैशकोड अक्सर उपयोग किया जाता है। उदाहरण के लिए, किसी HashMap में। अपरिवर्तनीय गारंटी है कि हैशकोड हमेशा एक ही होगा, ताकि यह बदलावों की चिंता किए बिना कैश किया जा सके। इसका मतलब यह है कि हर बार इसका उपयोग करने के लिए हैशकोड की गणना करने की कोई आवश्यकता नहीं है।


7
स्ट्रिंग पूल के बारे में आपकी समझ गलत है। स्ट्रिंग स्थिरांक प्रशिक्षु पूल में बनाई गई हैं, लेकिन इसमें उतना ही पाठ के साथ एक से अधिक स्ट्रिंग वस्तु के लिए पूरी तरह से संभव है। मैं मानता हूँ कि तार किया जा रहा है अपरिवर्तनीय पूलिंग सक्षम है, लेकिन वहाँ बहुत पूलिंग के रूप में नहीं है सा आप कहा गया है।
जॉन स्कीट

@JonSkeet आप सही हैं। स्ट्रिंग s1 = नया स्ट्रिंग ("परीक्षण"); जब तक हम मेथड इंटर्न () को नहीं कहते तब तक इंटरनैट पूल में स्टेटमेंट को नया स्ट्रींग कंटीन्यू बनाते हैं। स्ट्रिंग इंटर्न पूल के बारे में मेरे ज्ञान को गहरा करने के लिए धन्यवाद।
एलेक्स मैथ्यू

2
यह केवल स्ट्रिंग कंस्ट्रक्टर का उपयोग करने से अधिक है - लगभग कुछ भी जो एक नया स्ट्रिंग बनाता है, जैसे सबस्ट्रिंग, स्प्लिट, कॉनकट आदि नए स्ट्रिंग्स बनाएंगे। कंपाइल-टाइम कांस्टेंट यहां विशेष मामला है, आदर्श नहीं ...
जॉन स्कीट

@JonSkeet सबस्ट्रिंग (), कॉनैट (), रिप्लेस () आदि आंतरिक रूप से स्ट्रिंग कंस्ट्रक्टर का उपयोग करने के लिए एक स्ट्रिंग स्ट्रिंग बनाने के लिए उपयोग करते हैं। मेरे उत्तर को बेहतर बनाने के लिए धन्यवाद।
एलेक्स मैथ्यू

2
@JonSkeet - इन सभी उत्तरों का कहना है कि अपरिवर्तनीयता "सुरक्षा" में सुधार करती है, लेकिन यह नहीं समझाती कि कैसे। वे सभी एक अस्पष्ट dzone लेख से जुड़ते हैं जो या तो मदद नहीं करता है। जब कोड चल रहा होता है तो उत्तर / लिंक यह स्पष्ट नहीं करते हैं कि एक परिवर्तनशील स्ट्रिंग को कैसे बदला जा सकता है। क्या आप समझा सकते हैं?
मास्टरजो 2

25

हम यह सुनिश्चित नहीं कर सकते हैं कि जावा डिजाइनर वास्तव में डिजाइन करते समय क्या सोच रहे थे, Stringलेकिन हम केवल स्ट्रिंग अपरिवर्तनीयता से निकलने वाले फायदे के आधार पर इन कारणों का निष्कर्ष निकाल सकते हैं, जिनमें से कुछ हैं

1. लगातार स्थिर पूल का अस्तित्व

जैसा कि क्यों स्ट्रिंग स्ट्रिंग कॉन्स्टेंट पूल लेख में संग्रहित है , हर एप्लिकेशन बहुत अधिक स्ट्रिंग ऑब्जेक्ट बनाता है और जेवीएम को पहले बहुत सी स्ट्रिंग ऑब्जेक्ट बनाने और फिर उन्हें इकट्ठा करने से बचाने के लिए। JVM सभी स्ट्रिंग ऑब्जेक्ट को एक अलग मेमोरी क्षेत्र में संग्रहीत करता है जिसे स्ट्रिंग स्थिर पूल कहा जाता है और उस कैश्ड पूल से ऑब्जेक्ट्स का पुन: उपयोग करता है।

जब भी हम एक स्ट्रिंग शाब्दिक JVM बनाते हैं, तो पहले यह देखते हैं कि क्या शाब्दिक पहले से ही निरंतर पूल में मौजूद है या नहीं और यदि ऐसा है, तो नया संदर्भ एससीपी में उसी वस्तु की ओर इशारा करना शुरू कर देगा।

String a = "Naresh";
String b = "Naresh";
String c = "Naresh";

मूल्य के साथ ऊपर के उदाहरण स्ट्रिंग वस्तु में Nareshकेवल एक बार SCP में बनाया जाएगा और सभी संदर्भ a, b, cएक ही वस्तु है, लेकिन क्या को इंगित करता है, तो हम में परिवर्तन करने के लिए कोशिश करेंगे aजैसे a.replace("a", "")

आदर्श रूप में, aमूल्य होना चाहिए Nreshलेकिन b, cअपरिवर्तित रहना चाहिए क्योंकि एक अंतिम उपयोगकर्ता के रूप में हम aकेवल परिवर्तन कर रहे हैं । और हम जानते हैं a, सभी एक ही वस्तु की ओर इशारा कर रहे हैं b, cइसलिए यदि हम इसमें बदलाव करते हैं a, तो दूसरों को भी परिवर्तन को प्रतिबिंबित करना चाहिए।

लेकिन स्ट्रिंग इम्यूटेबिलिटी हमें इस परिदृश्य से बचाती है और स्ट्रिंग ऑब्जेक्ट की अपरिवर्तनीयता के कारण स्ट्रिंग ऑब्जेक्ट Nareshकभी नहीं बदलेगा। इसलिए जब हम aस्ट्रिंग ऑब्जेक्ट में बदलाव के बजाय कोई बदलाव करते हैं तो NareshJVM एक नई ऑब्जेक्ट को इसे असाइन करता है aऔर फिर उस ऑब्जेक्ट में बदलाव करता है।

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

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

2. थ्रेड सेफ्टी

एक वस्तु को थ्रेड-सेफ़ कहा जाता है, जब कई धागे उस पर काम कर रहे होते हैं, लेकिन उनमें से कोई भी अपने राज्य को भ्रष्ट करने में सक्षम नहीं होता है और वस्तु किसी भी समय किसी भी बिंदु पर एक ही स्थिति रखती है।

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

तो इसकी अपरिवर्तनीय प्रकृति के कारण स्ट्रिंग ऑब्जेक्ट को कई थ्रेड्स द्वारा साझा किया जा सकता है और भले ही इसे कई थ्रेड्स द्वारा हेरफेर किया जा रहा हो, यह इसके मूल्य को नहीं बदलेगा।

3. सुरक्षा

हर एप्लिकेशन में, हमें कई सीक्रेट्स पास करने होते हैं, जैसे यूजर का यूजर-नेम पासवर्ड, कनेक्शन यूआरएल और सामान्य तौर पर, यह सभी जानकारी स्ट्रिंग ऑब्जेक्ट के रूप में पास की जाती है।

अब मान लें कि अगर स्ट्रिंग प्रकृति में अपरिवर्तनीय नहीं होती, तो इससे एप्लिकेशन को गंभीर सुरक्षा का खतरा होता, क्योंकि इन मानों को बदलने की अनुमति है और यदि इसकी अनुमति है तो गलत तरीके से लिखे गए कोड या किसी अन्य व्यक्ति के कारण ये बदल सकते हैं हमारे चर संदर्भों तक पहुंच है।

4. क्लास लोडिंग

जैसा कि उदाहरण के साथ जावा में प्रतिबिंब के माध्यम से वस्तुओं को बनाने पर चर्चा की गई है , हम Class.forName("class_name")स्मृति में एक वर्ग को लोड करने के लिए विधि का उपयोग कर सकते हैं जो फिर से ऐसा करने के लिए अन्य तरीकों को कॉल करता है। और यहां तक ​​कि JVM कक्षाओं को लोड करने के लिए इन विधियों का उपयोग करता है।

लेकिन यदि आप स्पष्ट रूप से देखते हैं कि ये सभी विधियाँ वर्ग नाम को एक स्ट्रिंग ऑब्जेक्ट के रूप में स्वीकार करती हैं तो स्ट्रिंग्स का उपयोग जावा क्लास लोडिंग में किया जाता है और अपरिवर्तनीयता सुरक्षा प्रदान करती है कि सही क्लास लोड हो रही है ClassLoader

मान लीजिए अगर स्ट्रिंग अपरिवर्तनीय नहीं होती और हम लोड करने की कोशिश कर रहे होते हैं java.lang.Objectजो org.theft.OurObjectबीच-बीच में बदल जाते हैं और अब हमारी सभी वस्तुओं में एक व्यवहार होता है जिसका उपयोग कोई अवांछित वस्तु कर सकता है।

5. हैशकोड कैशिंग

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

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

हां, स्ट्रिंग ऑब्जेक्ट ऑब्जेक्ट निर्माण के समय अपने हैशकोड को कैश करता है जो कि हैशिंग संबंधित कार्यों के लिए महान उम्मीदवार बनाता है क्योंकि हैशकोड को फिर से गणना करने की आवश्यकता नहीं होती है जो हमें कुछ समय बचाते हैं। यही कारण है कि स्ट्रिंग का उपयोग ज्यादातर HashMapचाबियाँ के रूप में किया जाता है।

जावा में स्ट्रिंग अपरिवर्तनीय और अंतिम क्यों है, इस पर अधिक पढ़ें ।


1
सुरक्षा के बारे में - परिवर्तनशील स्ट्रिंग मान को स्मृति में कैसे बदला जा सकता है? कोई अन्य व्यक्ति हमारे चर संदर्भों तक कैसे पहुंच सकता है?
मास्टरजे २

यह इस बारे में नहीं है कि कोई उन संदर्भों तक कैसे पहुंच सकता है यदि कोई व्यक्ति उन तक पहुंचता है तो यह क्या है? जैसा कि उल्लेख किया गया है "यदि स्ट्रिंग प्रकृति में अपरिवर्तनीय नहीं होती है, तो यह आवेदन के लिए एक गंभीर सुरक्षा खतरा पैदा करेगा क्योंकि इन मूल्यों को बदलने की अनुमति है और यदि यह अनुमति है तो गलत तरीके से लिखे गए कोड या किसी अन्य व्यक्ति के कारण ये बदल सकते हैं। जिनके पास हमारे परिवर्तनशील संदर्भ हैं। "
नरेश जोशी

यहाँ कैसे मायने रखता है। इसका या तो संदर्भों तक पहुँच संभव है या नहीं। यदि संभव हो, तो क्या आप 1-2 तकनीकों का नाम दे सकते हैं *** (यानी कैसे) जो इसे करने के लिए इस्तेमाल किया जा सकता है? यदि संभव नहीं है, तो सुरक्षा के बारे में बात लागू नहीं होती है। *** उदाहरण - एक वेब ऐप के DB पर हमला करने के लिए एक तकनीक का नाम -> SQL इंजेक्शन। क्या आप संदर्भों पर हमला करने के लिए इस तरह की कोई तकनीक जानते हैं?
मास्टरजेओ 2

जैसा कि उल्लेख किया गया है, "यह गलत तरीके से लिखे गए कोड या किसी अन्य व्यक्ति द्वारा किए गए परिवर्तनों के कारण हो सकता है जिनके पास हमारे चर संदर्भों तक पहुंच है"। उदाहरण के लिए मान लें कि स्ट्रिंग उत्परिवर्तनीय है और आप कुछ विधि लिख रहे हैं जो एक स्ट्रिंग का उपयोग कर रहा है एक गुप्त रहस्य और फिर से उस स्ट्रिंग को बीच में कई अन्य विधि से पारित किया जा रहा है और उन तरीकों में से एक भी आपके द्वारा नहीं लिखा गया है और उस पद्धति ने उसमें कुछ बदलाव किए हैं स्ट्रिंग अब इन सभी तरीकों को कॉल करने के बाद नियंत्रण ने आपकी विधि वापस कर दी और आप उस स्ट्रिंग का फिर से उपयोग कर रहे हैं लेकिन इसे बदल दिया गया है।
नरेश जोशी

2
कृपया किसी भी संबद्धता का खुलासा करें और पोस्टिंग के माध्यम से अपनी साइट को बढ़ावा देने के तरीके के रूप में साइट का उपयोग न करें। देखिए मैं एक अच्छा उत्तर कैसे लिखूं?
यवेटे

21

DZone पर इस लेख के अनुसार सबसे महत्वपूर्ण कारण :

स्ट्रिंग कॉन्स्टेंट पूल ... यदि स्ट्रिंग उत्परिवर्तनीय है, तो एक संदर्भ के साथ स्ट्रिंग को बदलने से अन्य संदर्भों के लिए गलत मान हो जाएगा।

सुरक्षा

स्ट्रिंग को व्यापक रूप से कई जावा कक्षाओं के लिए पैरामीटर के रूप में उपयोग किया जाता है, जैसे नेटवर्क कनेक्शन, फाइलें खोलना, आदि अपरिवर्तनीय नहीं थे, एक कनेक्शन या फ़ाइल को बदल दिया जाएगा और गंभीर सुरक्षा खतरे को जन्म देगा। ...

आशा है इससे आपकी मदद होगी।


@JasonC मैं सिर्फ यह जानना चाहते हैं मेरे जवाब गलत है या नहीं.मैं पहले से ही साक्षात्कार और result.If के लिए इंतज़ार कर जवाब उनसे कहा भाग लिया था है सही और फिर चाहते हैं मैं चयन किया जाएगा
कमाल

1
मेरे ज्ञान के अनुसार आपका उत्तर सही है, लेकिन अपरिवर्तनीय अर्थ यह है कि संदर्भ कभी भी पॉइंटिंग लोकेशन नहीं बदलेगा। आपके साक्षात्कार के लिए सबसे अच्छा होगा।
JDGuide

1
यदि आपकी बात # 1 को स्वीकार करते हैं, तो सभी वस्तुओं को अपरिवर्तनीय होना चाहिए।
निकम्पर

हाय JDeveloper, मैंने आपके उत्तर को आपके उत्तर के स्रोत के लिए उचित गति देने के लिए संपादित किया है। सामग्री की शब्दशः प्रतियों के लिए हमेशा ब्लॉक कोट्स का उपयोग करना याद रखें। धन्यवाद!
निकोल

डीज़ोन लेख में स्ट्रिग्न पूल के संचालन के बारे में प्रमुख त्रुटियां हैं। यह केवल स्थिरांक के लिए है। Ergo कहा औचित्य अमान्य है।
लोरेन का

4

मैंने यह पोस्ट पढ़ी कि स्ट्रिंग जावा में अपरिवर्तनीय या अंतिम क्यों है और मान लीजिए कि निम्नलिखित सबसे महत्वपूर्ण कारण हो सकता है:

स्ट्रिंग जावा में अपरिवर्तनीय है क्योंकि स्ट्रिंग पूल में स्ट्रिंग ऑब्जेक्ट्स कैश्ड हैं । चूंकि कैश किए गए स्ट्रिंग शाब्दिक कई ग्राहकों के बीच साझा किए जाते हैं , इसलिए हमेशा एक जोखिम होता है, जहां एक ग्राहक की कार्रवाई अन्य सभी क्लाइंट को प्रभावित करेगी।


1

तुम सही हो। Stringजावा में String Poolशाब्दिक की अवधारणा का उपयोग करता है । जब एक स्ट्रिंग बनाई जाती है और यदि स्ट्रिंग पहले से ही पूल में मौजूद है, तो मौजूदा स्ट्रिंग का संदर्भ एक नई वस्तु बनाने और उसके संदर्भ को वापस करने के बजाय वापस आ जाएगा। यदि एक स्ट्रिंग अपरिवर्तनीय नहीं है, तो स्ट्रिंग को एक संदर्भ के साथ बदलना होगा अन्य संदर्भों के लिए गलत मान है।

मैं एक बात और जोड़ना चाहूंगा, क्योंकि Stringयह अपरिवर्तनीय है, यह मल्टी थ्रेडिंग के लिए सुरक्षित है और एक स्ट्रिंग उदाहरण को विभिन्न धागों में साझा किया जा सकता है। यह थ्रेड सुरक्षा के लिए सिंक्रनाइज़ेशन के उपयोग से बचें, स्ट्रिंग्स अंतर्निहित हैं thread safe


0

स्ट्रिंग क्लास का FINALमतलब है कि आप इसे विरासत में लाने और बुनियादी ढांचे को बदलने और स्टिंग को परिवर्तनशील बनाने के लिए कोई वर्ग नहीं बना सकते।

एक और बात उदाहरण चर और स्ट्रिंग वर्ग की विधियाँ प्रदान की जाती हैं जो इस प्रकार हैं कि आप Stringएक बार बनाई गई वस्तु को नहीं बदल सकते ।

आपके द्वारा जोड़ा गया कारण स्ट्रिंग को अपरिवर्तनीय नहीं बनाता है। यह सब कहता है कि स्ट्रिंग को ढेर में कैसे संग्रहीत किया जाता है। इसके अलावा स्ट्रिंग पूल प्रदर्शन में बहुत बड़ा अंतर बनाता है


11
यदि वर्ग को अंतिम रूप में घोषित किया जाता है, तो इसका मतलब है कि वर्ग को विरासत में नहीं मिला जा सकता है, लेकिन इसका मतलब यह नहीं है कि वर्ग के उदाहरण फ़ील्ड को नहीं बदला जा सकता है और इसलिए वर्ग अपरिवर्तनीय है।
दिमित्री बर्नेंको

@ ज़ीशान: आपके द्वारा दिए गए उदाहरण कक्षाएं सभी अपरिवर्तनीय हैं।
सियुआन रेन

0

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


0

जावा में अपरिवर्तनीय बनाए जाने वाले स्ट्रिंग का सबसे महत्वपूर्ण कारण सुरक्षा विचार है। अगला कैशिंग होगा ।

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

यहां गोसलिंग इंटरव्यू ट्रांसक्रिप्ट की जांच करें

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

आप अंत में ऑब्जेक्ट को दोहराने के लिए लगभग मजबूर हो रहे हैं क्योंकि आप नहीं जानते कि आप इसे प्राप्त करने के लिए हैं या नहीं। और अपरिवर्तनीय वस्तुओं के बारे में एक अच्छी बात यह है कि इसका उत्तर है, "हाँ, निश्चित रूप से आप करते हैं।" क्योंकि स्वामित्व का सवाल, जिसे बदलने का अधिकार है, वह मौजूद नहीं है।

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


0

महान जवाब के अलावा, मैं कुछ बिंदुओं को जोड़ना चाहता था। स्ट्रिंग्स की तरह, सरणी सरणी के शुरू करने से इसलिए यदि आप दो सरणियों बनाने के लिए एक संदर्भ रखती है arr1और arr2और था की तरह कुछ arr2 = arr1इस बात का संदर्भ कर देगा arr2के रूप में ही arr1है, इसलिए उनमें से एक में मान बदलने उदाहरण के लिए एक दूसरे के परिवर्तन में परिणाम होगा

public class Main {
    public static void main(String[] args) {
        int[] a = {1, 2, 3, 4};
        int[] b = a;
        a[0] = 8;
        b[1] = 7;
        System.out.println("A: " + a[0] + ", B: " + b[0]);
        System.out.println("A: " + a[1] + ", B: " + b[1]);
        //outputs
        //A: 8, B: 8
        //A: 7, B: 7
    }
}

इतना ही नहीं यह दुर्भावनापूर्ण उपयोगकर्ता द्वारा शोषण किया जा सकता है (और होगा) कोड में कीड़े का कारण होगा। मान लीजिए अगर आपके पास एक सिस्टम है जो एडमिन पासवर्ड को बदलता है। उपयोगकर्ता को पहले दर्ज करना होगा newPasswordऔर फिर oldPasswordयदि प्रोग्राम के अनुसार पासवर्ड बदल दिया जाए तो oldPasswordयह समान adminPassहै adminPass = newPassword। मान लीजिए कि नए पासवर्ड में व्यवस्थापक पासवर्ड के समान संदर्भ है, इसलिए खराब प्रोग्रामर tempउपयोगकर्ताओं को डेटा इनपुट करने से पहले व्यवस्थापक पासवर्ड रखने के लिए एक चर बना सकता है यदि इसके oldPasswordबराबर है tempतो पासवर्ड को बदल देता है अन्यथाadminPass = temp। यह जानकर कि कोई भी नया पासवर्ड आसानी से दर्ज कर सकता है और कभी भी पुराना पासवर्ड दर्ज नहीं कर सकता है और अब्रकदबरा के पास एडमिन एक्सेस है। एक और बात मैं जब क्यों JVM हर वस्तु के लिए एक नया स्ट्रिंग का निर्माण नहीं करता है और इसके लिए स्मृति में एक अद्वितीय स्थान है स्ट्रिंग्स के बारे में सीखने समझ में नहीं आया और तुम सिर्फ का उपयोग कर ऐसा कर सकते हैं new String("str");कारण आप नहीं चाहेंगे कि हमेशा उपयोग करने के लिए newहै क्योंकि यह स्मृति कुशल नहीं है और यह अधिक पढ़ें अधिकांश मामलों में धीमी है ।


0

तो HELLOअपने स्ट्रिंग है, तो आप बदल नहीं सकते HELLOकरने के लिए HILLO। इस संपत्ति को अपरिवर्तनीय संपत्ति कहा जाता है।

HELLO स्ट्रिंग को इंगित करने के लिए आपके पास कई पॉइंटर स्ट्रिंग चर हो सकते हैं।

लेकिन अगर HELLO char Array है तो आप HELLO को HILLO में बदल सकते हैं। उदाहरण के लिए,

char[] charArr = 'HELLO';
char[1] = 'I'; //you can do this

उत्तर:

प्रोग्रामिंग भाषाओं में अपरिवर्तनीय डेटा चर होते हैं ताकि इसे कुंजी, मूल्य जोड़ी में कुंजी के रूप में उपयोग किया जा सके। स्ट्रिंग वैरिएबल का उपयोग कुंजी / सूचक के रूप में किया जाता है, इसलिए वे अपरिवर्तनीय हैं


-1

इस Securityदृष्टिकोण से हम इस व्यावहारिक उदाहरण का उपयोग कर सकते हैं:

DBCursor makeConnection(String IP,String PORT,String USER,String PASS,String TABLE) {

    // if strings were mutable IP,PORT,USER,PASS can be changed by validate function
    Boolean validated = validate(IP,PORT,USER,PASS);

    // here we are not sure if IP, PORT, USER, PASS changed or not ??
    if (validated) {
         DBConnection conn = doConnection(IP,PORT,USER,PASS);
    }

    // rest of the code goes here ....
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.