एक वैरिएबल रिअसाइनमेंट रोकें
हालांकि ये उत्तर बौद्धिक रूप से दिलचस्प हैं, मैंने छोटा सरल उत्तर नहीं पढ़ा है:
जब आप चाहते हैं कि कीवर्ड अंतिम का उपयोग करें एक चर को फिर से एक अलग वस्तु को सौंपा जाने से रोकने के लिए कंपाइलर चाहिए।
चर एक स्थिर चर, सदस्य चर, स्थानीय चर, या तर्क / पैरामीटर चर है या नहीं, प्रभाव पूरी तरह से एक ही है।
उदाहरण
कार्रवाई में प्रभाव देखते हैं।
इस सरल विधि पर विचार करें, जहां दो चर ( arg और x ) दोनों को अलग-अलग वस्तुओं को फिर से सौंपा जा सकता है।
// Example use of this method:
// this.doSomething( "tiger" );
void doSomething( String arg ) {
String x = arg; // Both variables now point to the same String object.
x = "elephant"; // This variable now points to a different String object.
arg = "giraffe"; // Ditto. Now neither variable points to the original passed String.
}
स्थानीय चर को अंतिम रूप में चिह्नित करें । यह एक संकलक त्रुटि के परिणामस्वरूप होता है।
void doSomething( String arg ) {
final String x = arg; // Mark variable as 'final'.
x = "elephant"; // Compiler error: The final local variable x cannot be assigned.
arg = "giraffe";
}
इसके बजाय, हम अंतिम के रूप में पैरामीटर चर को चिह्नित करते हैं । यह भी एक संकलक त्रुटि में परिणाम है।
void doSomething( final String arg ) { // Mark argument as 'final'.
String x = arg;
x = "elephant";
arg = "giraffe"; // Compiler error: The passed argument variable arg cannot be re-assigned to another object.
}
कहानी का नैतिक:
यदि आप एक चर को हमेशा एक ही वस्तु पर इंगित करना चाहते हैं, तो चर को अंतिम रूप से चिह्नित करें ।
कभी भी पुन: तर्क न करें
अच्छी प्रोग्रामिंग प्रैक्टिस (किसी भी भाषा में) के रूप में, आपको कॉलिंग विधि द्वारा पारित ऑब्जेक्ट के अलावा किसी ऑब्जेक्ट के पैरामीटर / तर्क चर को फिर से असाइन नहीं करना चाहिए । ऊपर के उदाहरणों में, किसी को कभी भी लाइन नहीं लिखनी चाहिए arg =
। चूंकि मानव गलती करते हैं, और प्रोग्रामर मानव होते हैं, इसलिए संकलक से हमारी सहायता करने के लिए कहें। प्रत्येक पैरामीटर / तर्क चर को 'अंतिम' के रूप में चिह्नित करें ताकि संकलक ऐसे किसी भी पुन: असाइनमेंट को ढूंढ और चिह्नित कर सके।
सिंहावलोकन करने पर
जैसा कि अन्य उत्तरों में उल्लेख किया गया है ... किसी सरणी के अंत को पढ़ने के रूप में गूंगा गलतियों से बचने के लिए प्रोग्रामर की मदद करने के जावा के मूल डिजाइन लक्ष्य को देखते हुए, जावा को सभी पैरामीटर / तर्क चर को 'अंतिम' के रूप में स्वचालित रूप से लागू करने के लिए डिज़ाइन किया जाना चाहिए था। दूसरे शब्दों में, तर्क परिवर्तनशील नहीं होने चाहिए । लेकिन उस समय दृष्टि 20/20 की थी और उस समय जावा डिजाइनरों के हाथ पूरे थे।
तो, हमेशा final
सभी तर्कों में जोड़ें ?
क्या हमें final
घोषित किए जा रहे प्रत्येक और हर विधि पैरामीटर को जोड़ना चाहिए ?
- सिद्धांत रूप में, हाँ।
- व्यवहार में, नहीं।
➥ final
केवल तभी जोड़ें जब विधि का कोड लंबा या जटिल हो, जहां तर्क स्थानीय या सदस्य चर के लिए गलत हो सकता है और संभवतः फिर से सौंपा जा सकता है।
यदि आप एक तर्क को फिर से निर्दिष्ट नहीं करने के अभ्यास में खरीदते हैं, तो आप final
प्रत्येक में एक जोड़ने के लिए इच्छुक होंगे । लेकिन यह थकाऊ है और घोषणा को पढ़ने के लिए थोड़ा कठिन बना देता है।
लघु सरल कोड के लिए जहां तर्क स्पष्ट रूप से एक तर्क है, और न ही एक स्थानीय चर और न ही एक सदस्य चर, मैं इसे जोड़ने से परेशान नहीं करता हूं final
। यदि कोड काफी स्पष्ट है, तो मेरे पास कोई मौका नहीं है और न ही कोई अन्य प्रोग्रामर रखरखाव कर रहा है या गलती से तर्क चर को गलती से तर्क के अलावा किसी अन्य चीज के रूप में गलत कर रहा है, तो परेशान न करें। अपने स्वयं के काम में, मैं final
केवल अधिक या अधिक सम्मिलित कोड में जोड़ता हूं जहां एक तर्क स्थानीय या सदस्य चर के लिए गलत हो सकता है।
पूर्णता के लिए एक और मामला जोड़ा गया
public class MyClass {
private int x;
//getters and setters
}
void doSomething( final MyClass arg ) { // Mark argument as 'final'.
arg = new MyClass(); // Compiler error: The passed argument variable arg cannot be re-assigned to another object.
arg.setX(20); // allowed
// We can re-assign properties of argument which is marked as final
}