पृष्ठभूमि
तीन स्थान हैं जहाँ जावा में फाइनल दिखाया जा सकता है:
कक्षा को अंतिम बनाना कक्षा के सभी उपवर्ग को रोकता है। एक विधि को अंतिम बनाना विधि के उपवर्गों को ओवरराइड करने से रोकता है। फ़ील्ड फ़ाइनल बनाना, इसे बाद में बदलने से रोकता है।
गलत धारणाएं
ऐसे अनुकूलन हैं जो अंतिम तरीकों और क्षेत्रों के आसपास होते हैं।
एक अंतिम विधि हॉटस्पॉट को इनलाइनिंग के माध्यम से अनुकूलित करना आसान बनाता है। हालाँकि, अगर यह अंतिम नहीं है, तो भी HotSpot ऐसा करता है, क्योंकि यह इस धारणा पर काम करता है कि इसे अन्यथा सिद्ध नहीं किया गया है। इसके बारे में अधिक एसओ पर
एक अंतिम चर को आक्रामक रूप से अनुकूलित किया जा सकता है, और इसके बारे में और अधिक जेएलएस अनुभाग 17.5.3 में पढ़ा जा सकता है ।
हालांकि, उस समझ से एक के साथ बारे में पता होना चाहिए कि न तो इन अनुकूलन के एक बनाने के बारे में कर रहे हैं वर्ग फाइनल। क्लास फ़ाइनल करके कोई प्रदर्शन हासिल नहीं होता है।
किसी वर्ग के अंतिम पहलू का अपरिवर्तनीयता से कोई लेना-देना नहीं है। किसी के पास एक अपरिवर्तनीय वर्ग (जैसे बिगइन्टेगर ) हो सकता है जो अंतिम नहीं है, या एक ऐसा वर्ग जो परस्पर और अंतिम (जैसे स्ट्रिंगबर्ल ) है। यदि कोई वर्ग अंतिम होना चाहिए, तो यह निर्णय डिजाइन का प्रश्न है।
अंतिम नक्शा
स्ट्रिंग्स सबसे अधिक उपयोग किए जाने वाले डेटा प्रकारों में से एक है। वे नक्शे की कुंजी के रूप में पाए जाते हैं, वे उपयोगकर्ता नाम और पासवर्ड संग्रहीत करते हैं, वे वही हैं जो आप एक कीबोर्ड या वेब पेज पर एक फ़ील्ड से पढ़ते हैं। तार हर जगह हैं ।
मैप्स
पहली बात यह है कि यदि आप स्ट्रिंग को उप-वर्ग कर सकते हैं तो क्या होगा, इस बात का एहसास है कि कोई व्यक्ति एक स्थिर स्ट्रिंग वर्ग का निर्माण कर सकता है जो अन्यथा स्ट्रिंग प्रतीत होगा। इससे हर जगह मैप गड़बड़ हो जाएगा।
इस काल्पनिक कोड पर विचार करें:
Map t = new TreeMap<String, Integer>();
Map h = new HashMap<String, Integer>();
MyString one = new MyString("one");
MyString two = new MyString("two");
t.put(one, 1); h.put(one, 1);
t.put(two, 2); h.put(two, 2);
one.prepend("z");
यह एक मानचित्र के साथ सामान्य रूप से एक परिवर्तनशील कुंजी का उपयोग करने के साथ एक समस्या है, लेकिन मैं जिस चीज को पाने की कोशिश कर रहा हूं वह यह है कि अचानक मैप के बारे में बहुत सी चीजें टूट जाती हैं। प्रविष्टि अब मानचित्र में सही स्थान पर नहीं है। हाशपैप में, हैश वैल्यू (बदलनी चाहिए) बदल गई है और इस तरह यह अब सही प्रविष्टि पर नहीं है। ट्रीपैप में, पेड़ अब टूट गया है क्योंकि नोड्स में से एक गलत पक्ष पर है।
चूंकि इन कुंजियों के लिए स्ट्रिंग का उपयोग करना बहुत आम है, इसलिए स्ट्रिंग को अंतिम बनाकर इस व्यवहार को रोका जाना चाहिए।
आपको पढ़ने में रुचि हो सकती है क्यों स्ट्रिंग जावा में अपरिवर्तनीय है? स्ट्रिंग्स की अपरिवर्तनीय प्रकृति के बारे में अधिक जानकारी के लिए।
नापाक तार
स्ट्रिंग्स के लिए कई विभिन्न नापाक विकल्प हैं। विचार करें कि क्या मैंने एक स्ट्रिंग बनाई थी जो हमेशा बराबर होने पर वापस लौटी थी ... और कहा कि पासवर्ड चेक में पारित किया है? या फिर ऐसा किया है कि MyString को असाइनमेंट स्ट्रिंग की एक प्रति कुछ ईमेल पते पर भेजेगा?
जब आप स्ट्रिंग को उप-करने की क्षमता रखते हैं तो ये बहुत वास्तविक संभावनाएं होती हैं।
Java.lang स्ट्रिंग ऑप्टिमाइज़ेशन
जबकि इससे पहले कि मैं उल्लेख किया है कि अंतिम तेजी से स्ट्रिंग नहीं करता है। हालांकि, स्ट्रिंग क्लास (और अन्य वर्ग java.lang
) हर java.lang
समय स्ट्रिंग के लिए सार्वजनिक एपीआई के माध्यम से जाने के बजाय अन्य वर्गों को इंटर्नल के साथ छेड़छाड़ करने की अनुमति देने के लिए खेतों और विधियों के पैकेज स्तर के संरक्षण का लगातार उपयोग करते हैं । की तरह कार्य getChars रेंज जाँच या बिना lastIndexOf कि StringBuffer द्वारा किया जाता है, या निर्माता है कि शेयरों अंतर्निहित सरणी (ध्यान दें कि thats एक जावा 6 बात यह है कि स्मृति समस्याओं के कारण बदल गया था)।
यदि किसी ने स्ट्रिंग का उपवर्ग बनाया है, तो यह उन अनुकूलन को साझा करने में सक्षम नहीं होगा (जब तक कि यह java.lang
भी हिस्सा नहीं था , लेकिन यह एक सील पैकेज है )।
विस्तार के लिए कुछ डिजाइन करना कठिन है
विस्तार योग्य होने के लिए कुछ डिजाइन करना कठिन है । इसका मतलब है कि आप अपने इंटर्न्स के कुछ हिस्सों को उजागर करने में सक्षम होने के लिए कुछ और करने के लिए मिल गए हैं।
एक विस्तार योग्य स्ट्रिंग अपनी मेमोरी लीक को ठीक नहीं कर सकता था । इसके कुछ हिस्सों को उपवर्गों के संपर्क में लाना होगा और उस कोड को बदलने का मतलब होगा कि उपवर्ग टूट जाएंगे।
जावा बैकवर्ड संगतता में खुद को ढालता है और विस्तार करने के लिए कोर कक्षाएं खोलकर, कुछ चीजों को ठीक करने की क्षमता खो देता है जबकि तीसरे पक्ष के उपवर्गों के साथ संगणना बनाए रखता है।
चेकस्टाइल का एक नियम है कि यह लागू होता है (जो कि आंतरिक कोड लिखते समय मुझे वास्तव में निराश करता है) जिसे "DesignForExtension" कहा जाता है, जो लागू करता है कि हर वर्ग या तो है:
- सार
- अंतिम
- खाली क्रियान्वयन
जिसके लिए तर्कसंगत है:
यह एपीआई डिज़ाइन शैली सुपरक्लास को उपवर्गों द्वारा तोड़े जाने से बचाती है। नकारात्मक पक्ष यह है कि उप-वर्ग उनके लचीलेपन में सीमित हैं, विशेष रूप से वे सुपरक्लास में कोड के निष्पादन को रोक नहीं सकते हैं, लेकिन इसका मतलब यह भी है कि उप-वर्ग सुपर पद्धति को कॉल करने की भूल करके सुपरक्लास की स्थिति को भ्रष्ट नहीं कर सकते हैं।
क्रियान्वयन कक्षाओं को विस्तारित करने का अर्थ है कि उपवर्ग संभवतः उस वर्ग की स्थिति को भ्रष्ट कर सकते हैं जो इसके आधार पर है और इसे ऐसा बनाते हैं कि विभिन्न गारंटी जो सुपरक्लास देता है अमान्य हैं। स्ट्रिंग के रूप में जटिल कुछ के लिए, यह लगभग एक निश्चितता है कि इसका हिस्सा बदलने से कुछ टूट जाएगा ।
डेवलपर
डेवलपर होने के अपने हिस्से। संभावना है कि प्रत्येक डेवलपर के लिए अपने स्वयं के संग्रह के साथ अपने स्वयं के स्ट्रिंग उपवर्ग पैदा करेगा विचार करें utils उस में। लेकिन अब इन उपवर्गों को स्वतंत्र रूप से एक दूसरे को नहीं सौंपा जा सकता है।
WleaoString foo = new WleaoString("foo");
MichaelTString bar = foo; // This doesn't work.
इस तरह पागलपन की ओर जाता है। सभी जगह स्ट्रिंग करने के लिए कास्टिंग और यह देखने के लिए जाँच करें कि क्या स्ट्रिंग आपके स्ट्रिंग वर्ग का एक उदाहरण है या नहीं, तो उस एक के आधार पर एक नया स्ट्रिंग बनाना और ... बस, नहीं। मत करो।
मुझे यकीन है कि आप एक अच्छे स्ट्रिंग वर्ग लिख सकते हैं हूँ ... लेकिन उन पागल लोग हैं, जो सी लिखने ++ और से निपटने के लिए करने के लिए कई स्ट्रिंग कार्यान्वयन लिख छोड़ std::string
और char*
और बढ़ावा और से कुछ SString , और सब आराम ।
जावा स्ट्रिंग जादू
कई जादुई चीजें हैं जो जावा स्ट्रिंग्स के साथ करती हैं। इससे प्रोग्रामर के लिए भाषा में कुछ असंगतियों का सामना करना आसान हो जाता है। स्ट्रिंग पर उपवर्गों को आवंटित करना इन जादुई चीजों से निपटने के बारे में कुछ बहुत महत्वपूर्ण विचार रखेगा:
स्ट्रिंग लिटरल्स (JLS 3.10.5 )
कोड है कि एक करने की अनुमति देता है:
String foo = "foo";
यह पूर्णांक जैसे संख्यात्मक प्रकार के मुक्केबाजी के साथ भ्रमित नहीं होना है। आप नहीं 1.toString()
कर सकते, लेकिन आप कर सकते हैं "foo".concat(bar)
।
+
ऑपरेटर (JLS 15.18.1 )
जावा में कोई अन्य संदर्भ प्रकार उस पर उपयोग किए जाने वाले ऑपरेटर के लिए अनुमति नहीं देता है। स्ट्रिंग विशेष है। स्ट्रिंग कॉन्सेटेशन ऑपरेटर कंपाइलर स्तर पर भी काम करता है, ताकि रनटाइम के बजाय यह संकलित "foo" + "bar"
हो "foobar"
जाए।
स्ट्रिंग रूपांतरण (JLS 5.1.11 )
सभी वस्तुओं को स्ट्रिंग्स के संदर्भ में उपयोग करके सिर्फ स्ट्रिंग्स में परिवर्तित किया जा सकता है।
स्ट्रिंग इंटरस्टिंग ( JavaDoc )
स्ट्रिंग क्लास के पास स्ट्रिंग्स के पूल तक पहुंच है जो इसे ऑब्जेक्ट के कैनोनिकल अभ्यावेदन के लिए अनुमति देता है जो स्ट्रिंग प्रकार के साथ संकलित प्रकार पर आबादी है।
स्ट्रिंग के एक उपवर्ग की अनुमति देने का अर्थ होगा कि स्ट्रिंग के साथ ये बिट्स जो प्रोग्राम को आसान बनाते हैं या अन्य स्ट्रिंग प्रकार संभव होने पर करना बहुत मुश्किल या असंभव हो जाएगा।