java - अंतिम और प्रभावी रूप से अंतिम के बीच अंतर




lambda inner-classes (8)

मैं जावा 8 में लैम्बडास के साथ खेल रहा हूं और मुझे चेतावनी local variables referenced from a lambda expression must be final or effectively final । मुझे पता है कि जब मैं अज्ञात वर्ग के अंदर चर का उपयोग करता हूं तो उन्हें बाहरी वर्ग में अंतिम होना चाहिए, लेकिन फिर भी - अंतिम और प्रभावी रूप से अंतिम के बीच क्या अंतर है?


... जावा एसई 8 में शुरू होने पर, स्थानीय क्लास स्थानीय चर और संलग्न ब्लॉक के पैरामीटर तक पहुंच सकता है जो अंतिम या प्रभावी रूप से अंतिम होते हैं। एक चर या पैरामीटर जिसका मूल्य प्रारंभ होने के बाद कभी नहीं बदला जाता है प्रभावी रूप से अंतिम होता है।

उदाहरण के लिए, मान लीजिए कि परिवर्तनीय संख्या लम्बाई को अंतिम घोषित नहीं किया गया है, और आप फोन नम्बर कन्स्ट्रक्टर में चिह्नित असाइनमेंट स्टेटमेंट जोड़ते हैं:

PhoneNumber(String phoneNumber) {
    numberLength = 7;   // <== assignment to numberLength
    String currentNumber = phoneNumber.replaceAll(
        regularExpression, "");
    if (currentNumber.length() == numberLength)
        formattedPhoneNumber = currentNumber;
    else
        formattedPhoneNumber = null;
}

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

http://codeinventions.blogspot.in/2014/07/difference-between-final-and.html

http://docs.oracle.com/javase/tutorial/java/javaOO/localclasses.html


यदि आप स्थानीय चर में final संशोधक जोड़ सकते हैं, तो यह प्रभावी रूप से अंतिम था

Lambda अभिव्यक्तियों का उपयोग कर सकते हैं

  • स्थिर चर,

  • आवृत्ति के चर,

  • प्रभावी ढंग से अंतिम विधि पैरामीटर, और

  • प्रभावी रूप से अंतिम स्थानीय चर।

स्रोत: ओसीपी: ओरेकल प्रमाणित व्यावसायिक जावा एसई 8 प्रोग्रामर II स्टडी गाइड, जीन बॉयर्सकी, स्कॉट सेलिकॉफ



एक चर अंतिम या प्रभावी रूप से अंतिम होता है जब इसे एक बार शुरू किया जाता है और यह कभी भी अपने स्वामी वर्ग में उत्परिवर्तित नहीं होता है। और हम इसे लूप या आंतरिक कक्षाओं में शुरू नहीं कर सकते हैं

अंतिम :

final int number;
number = 23;

प्रभावी रूप से अंतिम :

int number;
number = 34;

नीचे यह चर अंतिम है , इसलिए आरंभ होने के बाद हम इसका मूल्य बदल नहीं सकते हैं। अगर हम कोशिश करते हैं तो हम संकलन त्रुटि प्राप्त करेंगे ...

final int variable = 123;

लेकिन अगर हम इस तरह एक चर बनाते हैं, तो हम इसका मूल्य बदल सकते हैं ...

int variable = 123;
variable = 456;

लेकिन जावा 8 में , सभी चर डिफ़ॉल्ट रूप से अंतिम होते हैं। लेकिन कोड में दूसरी पंक्ति का अस्तित्व इसे गैर-अंतिम बनाता है। इसलिए यदि हम उपरोक्त कोड से दूसरी पंक्ति को हटाते हैं, तो हमारा चर अब "प्रभावी रूप से अंतिम" है ...

int variable = 123;

तो .. किसी भी चर जो एक बार और केवल एक बार असाइन किया गया है, "प्रभावी रूप से अंतिम" है


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

[संपादित करें: हेनो वर्मीलेन, नीचे एक टिप्पणी में, इस नियम के लिए एक मामूली अपवाद बताते हैं। नियम अभी भी बहुत सरल और उपयोगी है, लेकिन वाक्यविन्यास नियमों का अर्थ है कि यह सार्वभौमिक रूप से लागू नहीं है।]


प्रभावी अंतिम विषय जेएलएस 4.12.4 में वर्णित है और अंतिम अनुच्छेद में स्पष्ट स्पष्टीकरण शामिल है:

यदि एक चर प्रभावी ढंग से अंतिम है, तो इसकी घोषणा में अंतिम संशोधक जोड़ना किसी भी संकलन-समय त्रुटियों को पेश नहीं करेगा। इसके विपरीत, अंतिम संशोधक को हटाए जाने पर एक स्थानीय चर या पैरामीटर जिसे अंतिम प्रोग्राम में अंतिम घोषित किया जाता है, प्रभावी रूप से अंतिम हो जाता है।


public class LambdaScopeTest {
    public int x = 0;        
    class FirstLevel {
        public int x = 1;    
        void methodInFirstLevel(int x) {

            // The following statement causes the compiler to generate
            // the error "local variables referenced from a lambda expression
            // must be final or effectively final" in statement A:
            //
            // x = 99; 

        }
    }    
}

जैसा कि अन्य ने कहा है, एक चर या पैरामीटर जिसका मूल्य प्रारंभ होने के बाद कभी नहीं बदला जाता है प्रभावी रूप से अंतिम होता है। उपर्युक्त कोड में, यदि आप आंतरिक वर्ग FirstLevel श्रेणी में x का मान FirstLevel तो संकलक आपको त्रुटि संदेश देगा:

लैम्ब्डा अभिव्यक्ति से संदर्भित स्थानीय चर अंतिम या प्रभावी रूप से अंतिम होना चाहिए।






java-8