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


141

जब मुझे पता चला कि java.lang.Stringजावा में कक्षा को अंतिम घोषित किया गया है, तो मैं सोच रहा था कि ऐसा क्यों है। मुझे फिर कोई उत्तर नहीं मिला, लेकिन यह पोस्ट: जावा में स्ट्रिंग क्लास की प्रतिकृति कैसे बनाएं? मुझे मेरी क्वेरी याद दिलाई।

ज़रूर, स्ट्रिंग मैं कभी भी ज़रूरत की सभी कार्यक्षमता प्रदान करता है, और मैंने कभी भी किसी भी ऑपरेशन के बारे में नहीं सोचा था जिसमें कक्षा स्ट्रिंग के विस्तार की आवश्यकता होगी, लेकिन फिर भी आप कभी नहीं जान पाएंगे कि किसी को क्या ज़रूरत हो सकती है!

तो, क्या किसी को पता है कि डिजाइनरों का इरादा क्या था जब उन्होंने इसे अंतिम रूप देने का फैसला किया था?


आपके जवाब के लिए आप सभी का धन्यवाद, खासकर ट्रूविल, ब्रूनो रीस और थिलो! काश मैं एक से अधिक उत्तर को सर्वश्रेष्ठ के रूप में चुन सकता, लेकिन दुर्भाग्य से ...!
एलेक्स Ntousias

1
इसके अलावा "ओह मैं सिर्फ स्ट्रिंग पर कुछ और उपयोगी तरीकों की जरूरत है" के प्रसार पर विचार करें जो पॉप अप करेंगे - जिनमें से सभी एक दूसरे का उपयोग नहीं कर सकते थे स्ट्रिंग्स क्योंकि वे एक अलग वर्ग थे।
थोरबजोरन रेव एंडरसन

इस उत्तर के लिए धन्यवाद इसके बहुत उपयोगी है। अब हमारे सामने दो तथ्य हैं। एक स्ट्रिंग एक अंतिम वर्ग है और इसका अपरिवर्तनीय है क्योंकि इसे बदला नहीं जा सकता है लेकिन इसे किसी अन्य ऑब्जेक्ट में भेजा जा सकता है। लेकिन किस बारे में: - स्ट्रिंग a = नया स्ट्रिंग ("test1"); फिर, s = "test2"; यदि स्ट्रिंग अंतिम श्रेणी की वस्तु है तो इसे कैसे संशोधित किया जा सकता है? मैं संशोधित अंतिम वस्तु का उपयोग कैसे कर सकता हूं। अगर मैंने गलत तरीके से कुछ भी पूछा तो कृपया मुझे बताएं।
सुरेश शर्मा

आप इस अच्छे लेख को देख सकते हैं ।
अनिकेत ठाकुर

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

जवाबों:


88

अपरिवर्तनीय वस्तुओं के रूप में लागू होने वाले तार होना बहुत उपयोगी है । आपको इसके बारे में अधिक समझने के लिए अपरिवर्तनीयता के बारे में पढ़ना चाहिए ।

अपरिवर्तनीय वस्तुओं का एक लाभ यह है कि

आप डुप्लिकेट को एक उदाहरण से इंगित करके साझा कर सकते हैं।

( यहां से )।

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


70
जब तक अंतिम कक्षाओं और अपरिवर्तनीय वस्तुओं के बीच कोई संबंध नहीं होता है जो मैं नहीं देख रहा हूं, मैं नहीं देखता कि आपका उत्तर प्रश्न से कैसे संबंधित है।
sepp2k

9
क्योंकि यदि यह अंतिम नहीं है, तो आप स्ट्रिंग स्ट्रिंग परम के रूप में किसी विधि को StringChild पारित कर सकते हैं, और यह परिवर्तनशील हो सकता है (क्योंकि एक बच्चा वर्ग राज्य परिवर्तन)।
हेलियोस

4
वाह! Downvotes? क्या आपको समझ में नहीं आता कि उपवर्ग कैसे अपरिवर्तनीयता से संबंधित है? मैं क्या समस्या है पर एक स्पष्टीकरण की सराहना करेंगे।
ब्रूनो रीस

7
@ ब्रूनो, पुनः: डाउनवोट्स: मैंने आपको डाउनवोट नहीं किया, लेकिन आप एक वाक्य जोड़ सकते हैं कि कैसे उपवर्गों को रोकना अपरिवर्तनीयता को लागू करता है। अभी, यह आधे-उत्तर की तरह है।
थिलो

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

60

यह एक अच्छा लेख है जो उपरोक्त उत्तरों पर पहले से वर्णित दो कारणों को रेखांकित करता है:

  1. सुरक्षा : सिस्टम बिना किसी चिंता के केवल पढ़ने योग्य जानकारी के संवेदनशील बिट्स को सौंप सकता है ताकि उन्हें बदल दिया जाएगा
  2. प्रदर्शन : अपरिवर्तनीय डेटा चीजों को धागा-सुरक्षित बनाने में बहुत उपयोगी है।

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


स्ट्रिंग का विस्तार समान और इंटर्न के साथ कहर होगा। जावाडॉक कहता है कि बराबरी:

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

यह मानते हुए java.lang.Stringकि अंतिम नहीं था, एक SafeStringबराबर हो सकता है String, और इसके विपरीत; क्योंकि वे वर्णों के समान अनुक्रम का प्रतिनिधित्व करेंगे।

यदि आप आवेदन किया, तो क्या होगा internएक करने के लिए SafeString- होगा SafeStringJVM की स्ट्रिंग पूल में जाने? तब ClassLoaderऔर SafeStringउसके संदर्भ में रखी गई सभी वस्तुएँ JVM के जीवनकाल के लिए बंद कर दी जाएंगी। आपको इस बारे में एक दौड़ की स्थिति मिलेगी कि पात्रों में से पहला क्रम कौन सा हो सकता है - शायद आपकी SafeStringजीत होगी, शायद एक String, या शायद SafeStringएक अलग क्लास लोडर (इस तरह एक अलग वर्ग) द्वारा भरी हुई।

यदि आप पूल में दौड़ जीतते हैं, तो यह एक सच्चा गायक होगा और लोग प्रतिबिंब के माध्यम से आपके पूरे वातावरण (सैंडबॉक्स) तक पहुंच सकते हैं secretKey.intern().getClass().getClassLoader()

या JVM इस छेद को सुनिश्चित कर सकता है कि पूल में केवल ठोस स्ट्रिंग ऑब्जेक्ट्स (और कोई उपवर्ग) जोड़े गए हैं।

यदि समान को इस तरह लागू किया गया था SafeString! = Stringतब SafeString.intern! = String.intern, और SafeStringपूल में जोड़ा जाएगा। पूल <Class, String>इसके बजाय एक पूल बन जाएगा <String>और आप सभी को पूल में प्रवेश करने की आवश्यकता होगी एक ताजा क्लास लोडर होगा।


2
बेशक प्रदर्शन कारण एक गिरावट है: स्ट्रिंग एक इंटरफ़ेस था मैं एक कार्यान्वयन प्रदान करने में सक्षम होगा जो मेरे आवेदन में बेहतर प्रदर्शन करता है।
स्टीफ़न एगरमोंट

28

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

अगर स्ट्रिंग उत्परिवर्तनीय या अंतिम नहीं थी, तो "mil.vogoon.DiskErasingWriter" को लोड करने के लिए "java.io.Writer" को बदलने का अनुरोध किया जा सकता था।

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


15

String जावा में एक बहुत ही मुख्य वर्ग है, कई चीजें इस पर निर्भर करती हैं कि वे एक निश्चित तरीके से काम करते हैं, उदाहरण के लिए अपरिवर्तनीय।

वर्ग बनाना finalउपवर्गों को रोकता है जो इन मान्यताओं को तोड़ सकते हैं।

ध्यान दें, अब भी, यदि आप प्रतिबिंब का उपयोग करते हैं, तो आप स्ट्रिंग्स को तोड़ सकते हैं (उनके मूल्य या हैशकोड को बदल सकते हैं)। सुरक्षा प्रबंधक के साथ प्रतिबिंब को रोका जा सकता है। अगर Stringऐसा नहीं होता finalतो हर कोई ऐसा कर सकता था।

अन्य वर्ग जो घोषित नहीं होते हैं, वे finalआपको कुछ टूटे हुए उपवर्गों को परिभाषित करने की अनुमति देते हैं ( Listउदाहरण के लिए, जो गलत स्थिति में जोड़ता है) हो सकता है , लेकिन कम से कम जेवीएम इसके मुख्य संचालन के लिए उन पर निर्भर नहीं होता है।


6
finalएक कक्षा में अपरिवर्तनीयता की गारंटी नहीं है। यह सिर्फ इस बात की गारंटी देता है कि एक वर्ग के अपरिवर्तनीय (जिनमें से एक अपरिवर्तनीय हो सकता है) को उप-वर्ग द्वारा नहीं बदला जा सकता है।
केविन ब्रॉक

1
@ केविन: हाँ। एक वर्ग पर अंतिम गारंटी देता है कि कोई उपवर्ग नहीं हैं। अपरिवर्तनीयता से कोई लेना-देना नहीं है।
थीलो

4
एक वर्ग का फ़ाइनल बनाना, स्वयं का नहीं, इसे अपरिहार्य बनाना है। लेकिन एक अपरिवर्तनीय वर्ग फाइनल करने से यह सुनिश्चित हो जाता है कि कोई भी ऐसा सबक्लास नहीं बनाता जो अपरिवर्तनीयता को तोड़ दे। शायद अपरिवर्तनीयता के बारे में बात करने वाले लोग बिल्कुल स्पष्ट नहीं थे कि उनका क्या मतलब है, लेकिन संदर्भ में समझा जाने पर उनके कथन सही हैं।
जे

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

6

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

  • धागा सुरक्षा
  • सुरक्षा
  • हीप का प्रबंधन जावा द्वारा किया जाता है (अलग-अलग साधारण ढेर के लिए जो अलग-अलग तरीके से कचरा एकत्रित किया जाता है)
  • स्मृति प्रबंधन

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

Aditionally जावा में अंतिम नहीं है जरूरी मतलब है कि वस्तु नहीं बदल सकते (यह उदाहरण के लिए C के लिए अलग है ++)। इसका मतलब यह है कि यह जिस पते को इंगित करता है वह बदल नहीं सकता है, लेकिन आप अभी भी इसे गुण और / या विशेषताओं को बदल सकते हैं। तो किसी मामले में अपरिवर्तनीयता और अंतिम के बीच अंतर को समझना वास्तव में महत्वपूर्ण हो सकता है।

HTH

संदर्भ:


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

2
साथ ही, किसी कक्षा का अंतिम कीवर्ड किसी फ़ील्ड के लिए अंतिम कीवर्ड से पूरी तरह से अलग होता है।
थिलो

1
ठीक है, सन जेवीएम पर, स्ट्रिंग्स जो इंटर्न हैं () एड परमिट-जीन में जा सकते हैं, जो कि ढेर का हिस्सा नहीं है। लेकिन यह निश्चित रूप से सभी स्ट्रिंग्स, या सभी जेवीएम के लिए नहीं होता है।
थिलो

2
सभी स्ट्रिंग्स उस क्षेत्र में नहीं जाती हैं, बस वे स्ट्रिंग्स जिन्हें इंटर्न किया गया है। इंटर्न शाब्दिक स्ट्रिंग्स के लिए स्वचालित है। (@Thilo, जैसे ही आपने अपनी टिप्पणी सबमिट की है)।
केविन ब्रॉक

इस उत्तर के लिए धन्यवाद इसके बहुत उपयोगी है। अब हमारे सामने दो तथ्य हैं। एक स्ट्रिंग एक अंतिम वर्ग है और इसका अपरिवर्तनीय है क्योंकि इसे बदला नहीं जा सकता है लेकिन इसे किसी अन्य ऑब्जेक्ट में भेजा जा सकता है। लेकिन किस बारे में: - स्ट्रिंग a = नया स्ट्रिंग ("test1"); फिर, s = "test2"; यदि स्ट्रिंग अंतिम श्रेणी की वस्तु है तो इसे कैसे संशोधित किया जा सकता है? मैं संशोधित अंतिम वस्तु का उपयोग कैसे कर सकता हूं। अगर मैंने गलत तरीके से कुछ भी पूछा तो कृपया मुझे बताएं।
सुरेश शर्मा

2

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


3
+1 "वंशानुक्रम के लिए डिज़ाइन करना कठिन है"। BTW, जो बलोच के "इफेक्टिव जावा" में बहुत अच्छी तरह से समझाया गया है।
सेल्स्के

2

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

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

यदि आप देखते हैं कि Stringकक्षा को घोषित कर दिया गया है

/** Cache the hash code for the string */
private int hash; // Default to 0

और hashcode()फ़ंक्शन निम्नानुसार है -

public int hashCode() {
    int h = hash;
    if (h == 0 && value.length > 0) {
        char val[] = value;

        for (int i = 0; i < value.length; i++) {
            h = 31 * h + val[i];
        }
        hash = h;
    }
    return h;
}

यदि यह पहले से ही कंप्यूटर है तो केवल मान लौटाएं।


2

यह सुनिश्चित करने के लिए कि हमें एक बेहतर कार्यान्वयन नहीं मिलता है। यह निश्चित रूप से एक इंटरफेस होना चाहिए था।

[संपादित करें] आह, वोटों से अधिक अव्यवस्था हो रही है। जवाब पूरी तरह से गंभीर है। मुझे कई बार मूर्खतापूर्ण स्ट्रिंग कार्यान्वयन के आसपास अपना कार्यक्रम बनाना पड़ा है, जिससे गंभीर प्रदर्शन और उत्पादकता हानि हुई है


2

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


2

अन्य उत्तरों (सुरक्षा, अपरिवर्तनीयता, प्रदर्शन) में वर्णित कारणों के अलावा यह ध्यान दिया जाना चाहिए कि Stringविशेष भाषा का समर्थन है। आप Stringशाब्दिक लिख सकते हैं और +ऑपरेटर के लिए समर्थन है । सब-क्लास को प्रोग्रामर की अनुमति String, जैसे कि हैक को प्रोत्साहित करेगा:

class MyComplex extends String { ... }

MyComplex a = new MyComplex("5+3i");
MyComplex b = new MyComplex("7+4i");
MyComplex c = new MyComplex(a + b);   // would work since a and b are strings,
                                      // and a string + a string is a string.

1

खैर, मेरे पास कुछ अलग विचार हैं मुझे यकीन नहीं है कि मैं सही हूं या नहीं, लेकिन जावा स्ट्रिंग एकमात्र ऐसी वस्तु है जिसे एक आदिम डेटा प्रकार के रूप में माना जा सकता है और मेरा मतलब है कि हम स्ट्रिंग नाम = "जावा के रूप में एक स्ट्रिंग ऑब्जेक्ट बना सकते हैं। । अब दूसरों की तरह आदिम datatypes जो copy by value not to reference by String के समान व्यवहार की अपेक्षा रखते हैं इसलिए स्ट्रिंग अंतिम है। Thats क्या मेरा यह सोचा था। कृपया नजरअंदाज करें अगर इसकी पूरी तरह से अतार्किक है।


1
मेरी राय में स्ट्रिंग कभी भी एक आदिम प्रकार की तरह व्यवहार नहीं करता है। "जावा" जैसा एक स्ट्रिंग शाब्दिक वास्तव में स्ट्रिंग क्लास का एक उद्देश्य है (आप उस पर डॉट ऑपरेटर का उपयोग कर सकते हैं, तुरंत समापन उद्धरण के बाद)। तो एक स्ट्रिंग चर के लिए एक शाब्दिक असाइन करना हमेशा की तरह ऑब्जेक्ट संदर्भ निर्दिष्ट कर रहा है। यह अलग है कि स्ट्रिंग क्लास में कंपाइलर में निर्मित भाषा-स्तरीय समर्थन है ... स्ट्रिंग ऑब्जेक्ट्स में डबल कोट्स में चीजों को बदलना, और जैसा कि ऊपर उल्लेख किया गया है + ऑपरेटर।
जॉर्जी

1

तार की अंतिमता भी उन्हें एक मानक के रूप में परिभाषित करती है। C ++ में आप स्ट्रिंग के उपवर्ग बना सकते हैं, इसलिए हर प्रोग्रामिंग शॉप का स्ट्रिंग का अपना संस्करण हो सकता है। इससे एक मजबूत मानक की कमी होगी।


1

मान लीजिए कि आपके पास एक Employeeवर्ग है जो एक विधि है greet। जबgreet विधि कहा जाता है तो यह केवल प्रिंट करता है Hello everyone!। तो यह विधि का अपेक्षित व्यवहार हैgreet

public class Employee {

    void greet() {
        System.out.println("Hello everyone!");
    }
}

अब, GrumpyEmployeeउपक्लास Employeeऔर ओवरराइड greetविधि को नीचे दिखाए अनुसार करें।

public class GrumpyEmployee extends Employee {

    @Override
    void greet() {
        System.out.println("Get lost!");
    }
}

अब नीचे दिए गए कोड में sayHelloविधि पर एक नज़र है । यहEmployee एक पैरामीटर के रूप में उदाहरण और ग्रीटिंग विधि को यह कहते हुए उम्मीद करता है कि यह कहेगा Hello everyone!लेकिन हमें जो मिलता है वह है Get lost!। व्यवहार में यह बदलाव इस वजह से हैEmployee grumpyEmployee = new GrumpyEmployee();

public class TestFinal {
    static Employee grumpyEmployee = new GrumpyEmployee();

    public static void main(String[] args) {
        TestFinal testFinal = new TestFinal();
        testFinal.sayHello(grumpyEmployee);
    }

    private void sayHello(Employee employee) {
        employee.greet(); //Here you would expect a warm greeting, but what you get is "Get lost!"
    }
}

अगर क्लास की गई तो इस स्थिति से बचा जा सकता Employeeहै final। अब यह आपकी कल्पना पर निर्भर करता है कि अव्यवस्थित प्रोग्रामर अराजकता की मात्रा का कारण बन सकता है या नहींString क्लास घोषित नहीं किया गया था final


0

क्या जेवीएम जानता है कि क्या अपरिवर्तनीय है? उत्तर है, निरंतर पूल में सभी अपरिवर्तनीय क्षेत्र शामिल हैं, लेकिन सभी अपरिवर्तनीय फ़ील्ड / ऑब्जेक्ट केवल निरंतर पूल में संग्रहीत नहीं किए जाते हैं। केवल हम इसे इस तरह से लागू करते हैं कि यह अपरिवर्तनीयता और इसकी विशेषताओं को प्राप्त करता है। CustomString को MarkerInterface का उपयोग करके अंतिम रूप दिए बिना लागू किया जा सकता है, जो इसके पूलिंग के लिए जावा विशेष व्यवहार प्रदान करेगा, इस सुविधा का अभी भी इंतजार है!


0

अधिकांश उत्तर अपरिवर्तनीयता से संबंधित हैं - स्ट्रिंग प्रकार की एक वस्तु को जगह में अपडेट क्यों नहीं किया जा सकता है। यहाँ बहुत अच्छी चर्चा है, और जावा समुदाय एक प्रमुख के रूप में अपरिवर्तनीयता को अपनाने के लिए अच्छा करेगा। (मेरी सांस नहीं रोकना।)

हालाँकि ओपी का सवाल यह है कि यह अंतिम क्यों है - इसे क्यों नहीं बढ़ाया जा सकता है। यहाँ कुछ लोगों ने इसे लिया, लेकिन मैं ओपी के साथ सहमत हूँ कि यहाँ एक वास्तविक अंतर है। अन्य भाषाएं देवों को एक प्रकार के लिए नए नाममात्र प्रकार बनाने की अनुमति देती हैं। उदाहरण के लिए हास्केल में मैं निम्नलिखित नए प्रकार बना सकता हूं जो पाठ के रूप में रन-टाइम पर समान हैं, लेकिन बाध्यकारी समय पर सुरक्षा प्रदान करते हैं।

newtype AccountCode = AccountCode Text
newtype FundCode = FundCode Text

तो मैं निम्नलिखित सुझाव को जावा भाषा में वृद्धि के रूप में आगे रखूंगा:

newtype AccountCode of String;
newtype FundCode of String;

AccountCode acctCode = "099876";
FundCode fundCode = "099876";

acctCode.equals(fundCode);  // evaluates to false;
acctCode.toString().equals(fundCode.toString());  // evaluates to true;

acctCode=fundCode;  // compile error
getAccount(fundCode);  // compile error

(या शायद हम जावा से खुद को निकालना शुरू कर सकते हैं)


-1

यदि आप एक बार एक स्ट्रिंग बनाते हैं तो यह विचार करेगा कि, यह एक वस्तु है यदि आप इसे संशोधित करना चाहते हैं, तो यह संभव नहीं है, यह नई वस्तु का निर्माण करेगा।


कृपया अपना उत्तर स्पष्ट करें।
मार्को पोपोविक
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.