हम यह सुनिश्चित नहीं कर सकते हैं कि जावा डिजाइनर वास्तव में डिजाइन करते समय क्या सोच रहे थे, 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चाबियाँ के रूप में किया जाता है।
जावा में स्ट्रिंग अपरिवर्तनीय और अंतिम क्यों है, इस पर अधिक पढ़ें ।