String अपरिवर्तनीय है * लेकिन इसका केवल यही अर्थ है कि आप इसे अपने सार्वजनिक API का उपयोग करके नहीं बदल सकते।
आप यहां क्या कर रहे हैं, प्रतिबिंब का उपयोग करके सामान्य एपीआई को दरकिनार कर रहा है। उसी तरह, आप एनम के मूल्यों को बदल सकते हैं, इंटेगर ऑटोबॉक्सिंग आदि में उपयोग की जाने वाली लुकअप तालिका को बदल सकते हैं।
अब, कारण s1और s2परिवर्तन मूल्य, यह है कि वे दोनों एक ही प्रशिक्षु स्ट्रिंग को संदर्भित करते हैं। संकलक ऐसा करता है (जैसा कि अन्य उत्तरों द्वारा उल्लेख किया गया है)।
कारण s3है नहीं वास्तव में एक सा मेरे लिए आश्चर्य की बात थी, के रूप में मैंने सोचा कि यह साझा करेंगे valueसरणी ( यह जावा के पुराने संस्करण में किया था , जावा 7u6 से पहले)। हालांकि, के स्रोत कोड को Stringदेखते हुए , हम देख सकते हैं कि एक विकल्प के लिए valueवर्ण सरणी वास्तव में कॉपी (उपयोग Arrays.copyOfRange(..)) है। यही कारण है कि यह अपरिवर्तित है।
आप SecurityManagerइस तरह के काम करने के लिए दुर्भावनापूर्ण कोड से बचने के लिए एक स्थापित कर सकते हैं। लेकिन ध्यान रखें कि कुछ लाइब्रेरी इस तरह के रिफ्लेक्शन ट्रिक्स (आमतौर पर ORM टूल्स, AOP लाइब्रेरी आदि) का उपयोग करने पर निर्भर करती हैं।
*) मैंने शुरू में लिखा था कि Stringवास्तव में अपरिवर्तनीय नहीं हैं, बस "प्रभावी अपरिवर्तनीय"। यह वर्तमान कार्यान्वयन में भ्रामक हो सकता है String, जहां valueसरणी वास्तव में चिह्नित है private final। यह अभी भी ध्यान देने योग्य है, हालांकि, जावा में एक सरणी को अपरिवर्तनीय घोषित करने का कोई तरीका नहीं है, इसलिए उचित एक्सेस संशोधक के साथ, इसकी कक्षा के बाहर इसे उजागर नहीं करने के लिए भी ध्यान रखा जाना चाहिए।
जैसा कि यह विषय अत्यधिक लोकप्रिय लगता है, यहाँ कुछ ने आगे पढ़ने का सुझाव दिया है: हेंज काबुत्ज़ का प्रतिबिंब पागलपन जावाज़ोन 2009 से बात करता है, जो ओपी में बहुत सारे मुद्दों को शामिल करता है, साथ ही अन्य प्रतिबिंब ... अच्छी तरह से ... पागलपन।
यह कवर करता है कि यह कभी-कभी उपयोगी क्यों होता है। और क्यों, ज्यादातर समय, आपको इससे बचना चाहिए। :-)