उद्योग में 'अंतिम' कीवर्ड का उपयोग इतना कम क्यों किया जाता है? [बन्द है]


14

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

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

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

क्या कोई कारण है? क्या अंदर से सब कुछ बदलने योग्य है यह एक सामान्य डिजाइन प्रतिमान है?


माइक्रो ऑप्टिमाइज़ेशन में, finalफ़ील्ड सेट करने में फ़ील्ड लिखने के समान शब्दार्थ होते हैं volatile, और फिर उन्हें पढ़ने के बाद अस्थिर पढ़ने के शब्दार्थ की आवश्यकता होती है, यह हमेशा वह नहीं होता जो आप चाहते हैं
शाफ़्ट सनकी

5
@ratchet: मुझे लगता है कि यह आपकी कक्षाओं को अपरिवर्तनीय बनाने के बारे में है, जैसा कि कार्यात्मक प्रोग्रामिंग में है।
जोनास

@Kwebble: शायद अधिक महत्वपूर्ण बात, व्यक्तिगत स्ट्रिंग उदाहरण अपरिवर्तनीय हैं।
मैट्रिक्सप्रोग

जवाबों:


9

मुझे संदेह है कि जिस कारण से आप इसे नहीं देख रहे हैं, क्योंकि JDK को विस्तारित करने के लिए डिज़ाइन किया गया है (यह वह आधार है जहां से आपके सभी कार्यक्रम बनाए जाते हैं)। एप्लिकेशन कोड का उपयोग करने के लिए यह बिल्कुल भी असामान्य नहीं होगा। मैं लाइब्रेरी कोड में भी इसका बहुत कुछ देखने की उम्मीद नहीं करूंगा (जैसा कि पुस्तकालयों को अक्सर विस्तार के लिए भी डिज़ाइन किया जाता है)।

कुछ अच्छे ओपन सोर्स प्रोजेक्ट्स पर एक नज़र डालने की कोशिश करें और मुझे लगता है कि आप और अधिक पाएंगे।

.NET दुनिया में आप जावा में जो देख रहे हैं, उसके विपरीत, मैंने कई बार यह तर्क सुना है कि sealedडिफ़ॉल्ट रूप से क्लैस होना चाहिए (एक वर्ग के लिए अंतिम रूप से लागू) और डेवलपर स्पष्ट रूप से अन-सील होना चाहिए यह।


2
मैं कुछ JDK वर्गों के कई निजी या संरक्षित सदस्यों का भी उल्लेख कर रहा था जो स्पष्ट रूप से "एक बार स्पॉन, कभी नहीं" ऑब्जेक्ट चर को ओवरराइड करते हैं। विशेष रूप से स्विंग पैकेज में। वे 'अंतिम' के लिए एकदम सही उम्मीदवार हैं, क्योंकि वहाँ एक अशक्त सूचक के साथ प्रतिस्थापन घटकों का उपयोग करते समय त्रुटियों को जन्म देगा।
ऑरेलियन रिबोन

1
@ Aurélien: यदि यह आपको किसी भी बेहतर का एहसास कराता है, तो .NET फ्रेमवर्क की कई कक्षाएं सील हो जाती हैं, कुछ उपयोगकर्ताओं के लिए जो अपनी कार्यक्षमता के साथ फ्रेमवर्क कक्षाओं का विस्तार करना चाहते हैं। हालांकि, एक्सटेंशन लिमिट्स
रॉबर्ट हार्वे

1
मुझे लगता है कि यह विस्तार से बचने की तुलना में अपरिवर्तनीयता के बारे में अधिक है। दूसरे शब्दों में finalखेतों पर और तरीकों पर नहीं। अपरिवर्तनीय कक्षाएं भी विस्तारित करने के लिए डिज़ाइन की जा सकती हैं।
जोनास

15

यह finalबताने के लिए उपयोग करने में समस्या है कि कुछ केवल-पढ़ने के लिए है, यह केवल वास्तव में आदिम प्रकारों के लिए काम करता है int, charआदि। जावा में सभी वस्तुओं को वास्तव में एक (प्रकार) सूचक का उपयोग करने के लिए संदर्भित किया जाता है। परिणामस्वरूप, जब आप finalकिसी ऑब्जेक्ट पर कीवर्ड का उपयोग करते हैं, तो आप केवल यह कह रहे हैं कि संदर्भ केवल-पढ़ने के लिए है, ऑब्जेक्ट अभी भी परिवर्तनशील है।

इसका अधिक उपयोग किया जा सकता है यदि यह वास्तव में वस्तु को केवल पढ़ने योग्य बनाता है। C ++ में ठीक यही constहोता है और परिणामस्वरूप यह बहुत अधिक उपयोगी और भारी उपयोग किया जाने वाला कीवर्ड है।

finalइस तरह की चीज़ों से बनी किसी भी उलझन से बचने के लिए मैं एक जगह पर कीवर्ड का बहुत अधिक उपयोग करता हूँ :

public void someMethod(FancyObject myObject) {
    myObject = new FancyObject();
    myObject.setProperty(7);
}
...
public static void main(final String[] args) {
    ...
    FancyObject myObject = new FancyObject();
    someOtherObject.someMethod(myObject);
    myObject.getProperty(); // Not 7!
}

इस उदाहरण में यह स्पष्ट प्रतीत होता है कि यह काम क्यों नहीं करता है लेकिन यदि someMethod(FancyObject)बड़ा और जटिल भ्रम हो सकता है। इससे परहेज क्यों नहीं?

यह सूर्य का भी हिस्सा है (या Oracle अब मुझे लगता है) कोडिंग मानकों।


1
यदि finalजावा एपीआई कक्षाओं में अधिक उपयोग किया गया है , तो अधिकांश वस्तुएं कई स्काला लाइब्रेरी के साथ अपरिवर्तनीय थीं। फिर ऑब्जेक्ट फ़ील्ड बनाना finalकई मामलों में कक्षा को अपरिवर्तनीय बनाता है। इस डिजाइन पहले से ही प्रयोग किया जाता है BigDecimalऔर String
जोनास

@ जोनास मैंने कहा कि प्रश्न 4 अंक के बारे में अधिक था, क्योंकि वह कह रहा था कि लोग आसानी से देख सकते हैं कि क्या केवल पढ़ने योग्य चर हैं "और उसके अनुसार उत्तर दिया।" शायद मुझे जवाब में उस धारणा को शामिल करना चाहिए था।
ज्ञान उर्फ ​​गैरी ब्यन

ध्यान रखें कि ऐसे समय होते हैं जब आप पैरामीटर को पुन: असाइन करना चाहते हैं। उदाहरण के लिए एक स्ट्रिंग पैरामीटर को ट्रिम कर रहा है।
स्टीव कू

@ मैं पहले से ही उस स्थिति में असाइन किए जाने के लिए एक नया चर बनाता हूं।
ज्ञान उर्फ ​​गैरी ब्यून

1
@ गैरी, मेरे लिए कम से कम, यह बहुत दुर्लभ है कि कीड़े / भ्रम एक पैरामीटर को पुन: असाइन करने के कारण होते हैं। मैं बहुत अधिक अव्यवस्था मुक्त कोड चाहता हूँ और एक बग पैदा करने वाले पैरामीटर को पुन: असाइन करने के दूरस्थ अवसर को स्वीकार करता हूँ। कोड लिखते / संशोधित करते समय बस सावधान रहें।
स्टीव कू

4

मैं सहमत हूं कि finalकीवर्ड पठनीयता में सुधार करता है। किसी वस्तु के अपरिवर्तनीय होने पर समझना आसान हो जाता है। हालांकि, जावा में यह अत्यंत क्रियात्मक है, विशेष रूप से (मेरी राय में) जब मापदंडों पर उपयोग किया जाता है। यह कहने के लिए नहीं है कि लोगों को इसका उपयोग नहीं करना चाहिए क्योंकि यह क्रिया है, बल्कि वे इसका उपयोग नहीं करते हैं क्योंकि यह क्रिया है।

कुछ अन्य भाषा, जैसे कि स्कैला, अंतिम घोषणाएं ( वैल ) करना बहुत आसान बनाती हैं । इन भाषाओं में, अंतिम घोषणाएं चर की तुलना में अधिक सामान्य हो सकती हैं।

ध्यान दें कि अंतिम कीवर्ड के कई अलग-अलग उपयोग हैं। आपकी पोस्ट में ज्यादातर आइटम 2 और 3 शामिल हैं।

  1. अंतिम कक्षाएं (JLS 8.1.1.2)
  2. अंतिम फ़ील्ड (JLS 8.3.1.2)
  3. अंतिम तरीके (JLS 8.4.3.3)
  4. अंतिम चर (जेएलएस 4.12.4)

2

खैर, आधिकारिक जावा कोड कन्वेंशनों के साथ शुरू करने के लिए न तो पक्ष लेते हैं और न ही विशेष उपयोग पर प्रतिबंध लगाते हैं final। यही है, JDK डेवलपर्स अपने पसंद के तरीके को चुनने के लिए स्वतंत्र हैं।

मैं उनके दिमाग को नहीं पढ़ सकता लेकिन मेरे लिए, इस बात पर वरीयता कि क्या उपयोग करना है finalया नहीं यह ध्यान देने की बात है। इस बात का कोई फर्क नहीं है कि मेरे पास कोड पर पूरी तरह ध्यान केंद्रित करने के लिए पर्याप्त समय है या नहीं

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

यह JIT को थोड़ा बढ़ावा दे सकता है, और जबकि यह बहुत सीमित है, यह नुकसान नहीं पहुंचा सकता है

ऊपर की तरह तर्क फिसलन है। समयपूर्व अनुकूलन नुकसान पहुंचा सकता है; डोनाल्ड नुथ इसे "सभी बुराई की जड़" कहने के लिए जाता है । इसे आप फँसने न दें। गूंगा कोड लिखें


2

हाल ही में मैंने ग्रहण आईडीई में "सेव एक्ट्स" फीचर की खुशी का पता लगाया। मैं इसे अपने कोड को पुन: स्वरूपित करने के लिए बाध्य कर सकता हूं, लापता @Overrideएनोटेशन सम्मिलित कर सकता हूं , और कुछ निफ्टी सामान कर सकता हूं जैसे कि अभिव्यक्ति में अनावश्यक कोष्ठक को हटा दें या finalहर बार जब भी मैं हिट करता हूं, तो हर जगह स्वचालित रूप से कीवर्ड डाल दें ctrl + S। मैंने उन कुछ ट्रिगर्स को सक्रिय किया और, लड़का, यह बहुत मदद करता है!

यह पता चला कि उनमें से कई ट्रिगर्स मेरे कोड के लिए एक त्वरित स्वच्छता जांच की तरह काम करते हैं।

  • मैंने एक विधि को ओवरराइड करने का इरादा किया था लेकिन जब मैंने मारा तो एनोटेशन नहीं दिखा ctrl + s? - शायद मैं पैरामीटर प्रकार कहीं खराब कर दिया!
  • कुछ कोष्ठक को बचाने पर कोड से हटा दिया गया था? - हो सकता है कि प्रोग्रामर के लिए लॉजिक एक्सप्रेशन बहुत कठिन हो। अन्यथा, मैं उन कोष्ठकों को पहले स्थान पर क्यों जोड़ूंगा?
  • वह पैरामीटर या स्थानीय चर नहीं है final। यह है है अपने मूल्य बदलने के लिए?

यह पता चला कि कम चर मुझे डिबग समय में कम परेशानी को बदलते हैं। केवल चर के मूल्य का आप कितनी बार अनुसरण कर रहे थे, यह पता लगाने के लिए कि यह किसी तरह 5 से 7 में बदलता है? "यह कैसे हो सकता है ?!" आप अपने आप से पूछते हैं और अगले दो घंटे बिताते हैं और अनगिनत तरीकों से यह पता लगाने के लिए कि आपने अपने तर्क में गलती की है। और इसे ठीक करने के लिए आपको एक और ध्वज, कुछ शर्तों को जोड़ना होगा और ध्यान से कुछ मूल्यों को यहां और वहां बदलना होगा।

ओह, मुझे डिबगिंग से नफरत है! जितनी बार मैं डिबगर चलाता हूं मुझे लगता है कि मेरा समय समाप्त हो रहा है और मुझे अपने बचपन के कुछ सपनों को सच करने के लिए उस समय की सख्त जरूरत है! डिबगिंग के साथ नरक करने के लिए! मतलब कोई और अधिक रहस्यमय मूल्य परिवर्तन नहीं है। मेरे कोड में अधिक s => कम भड़कीला भाग => कम बग => अधिक समय अच्छी चीजें करने के लिए!finalfinal

के रूप में finalवर्गों और तरीकों मैं वास्तव में परवाह नहीं है। मुझे बहुरूपता पसंद है। बहुरूपता का अर्थ है पुन: उपयोग का अर्थ है कम कोड का मतलब कम बग। JVM वैसे भी अवमूल्यन और विधि inlining के साथ एक बहुत अच्छा काम करता है, इसलिए मुझे अनावश्यक प्रदर्शन लाभों के लिए कोड पुन: उपयोग के लिए हत्या की संभावनाओं में कोई मूल्य नहीं दिखता है।


finalकोड में उन सभी को देखकर पहली बार में कुछ ध्यान भंग हो रहा है और इसका उपयोग करने में भी समय लगता है। मेरी टीम के कुछ साथी अभी भी बहुत सारे finalकीवर्ड देखकर बहुत हैरान हैं । काश, इसके लिए विशेष सिंटैक्स रंग के लिए आईडीई में एक सेटिंग थी। मुझे इसे ग्रे के कुछ शेड (जैसे एनोटेशन) में बदलने में खुशी होगी, ताकि कोड पढ़ते समय वे बहुत विचलित न हों। वर्तमान में ग्रहण के लिए returnऔर सभी अन्य कीवर्ड के लिए एक अलग रंग है, लेकिन इसके लिए नहीं final


1
आप शायद OCaml या F # जैसी कार्यात्मक भाषाओं में विचार कर सकते हैं। इन भाषाओं में बहुत कम डिबगिंग की आवश्यकता होती है, इसका एक कारण यह है कि सब कुछ केवल डिफ़ॉल्ट रूप से पढ़ा जाता है। सीधे शब्दों में कहें, एक बार सौंपा, एक कार्यात्मक भाषा में एक चर नहीं बदलता है।
हाबिल

1
हाँ, मुझे पता है कि और मैं वास्तव में समय-समय पर कुछ एमएल कोड लिखता हूं - यहीं से मुझे मेरी प्रेरणा मिली :) यह उस भाषा के बारे में नहीं है जिसका आप उपयोग करते हैं बल्कि आपके द्वारा लागू सिद्धांतों और तकनीकों के बारे में है। हास्केल और doअंकन के साथ सभी अनिवार्य हो सकते हैं :) निश्चित रूप से, जावा कार्यात्मक शैली में लिखने के लिए सबसे अच्छी भाषा नहीं है, लेकिन कम से कम यह आपको मजबूत कोड लिखने की अनुमति देता है-और यह कि मुझे वास्तव में क्या परवाह है।
एंड्रयू Андрей Листочкин
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.