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


351

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


2
जवाब के बहुत सारे, फिर भी सभी अनिवार्य रूप से "कोई अंतर नहीं है।" लेकिन क्या यह वास्तव में सच है? दुर्भाग्य से, मैं जावा 8. के लिए एक भाषा विशिष्टता को खोजने के लिए नहीं कर पा रहे
Aleksandr Dubinsky

3
@AleksandrDubinsky docs.oracle.com/javase/specs
eis

@AleksandrDubinsky "वास्तव में" सच नहीं है। मुझे इस नियम का एक अपवाद मिला। एक स्थिरांक के साथ एक स्थानीय चर कंपाइलर के लिए एक स्थिर अभिव्यक्ति नहीं है। जब तक आप स्पष्ट रूप से अंतिम कीवर्ड नहीं जोड़ते हैं, तब तक आप स्विच / केस में इस तरह के चर का उपयोग नहीं कर सकते। जैसे "int k = 1; switch (someInt) {केस k: ..."।
हेन्नो वर्म्यूलेन

जवाबों:


234

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

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

public class OutterClass {  

  int numberLength; // <== not *final*

  class PhoneNumber {

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

  ...

  }

...

}

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

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

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


68
+1 नोट: यदि कोई संदर्भ नहीं बदला गया है, तो यह प्रभावी रूप से अंतिम है भले ही ऑब्जेक्ट संदर्भित हो।
पीटर लॉरी

1
@stanleyerror यह कुछ मदद हो सकती है: stackoverflow.com/questions/4732544/…

1
मुझे लगता है कि का एक उदाहरण की तुलना में अधिक उपयोगी नहीं प्रभावी ढंग से अंतिम, जब कुछ का एक उदाहरण है है को प्रभावी ढंग से अंतिम। हालांकि वर्णन स्पष्ट करता है। यदि कोई कोड परिवर्तन नहीं करता है, तो var को अंतिम घोषित नहीं किया जाना चाहिए।
स्काइचन

1
उदाहरण गलत है। यह कोड पूरी तरह से (बिना डॉट्स के) संकलित करता है। कंपाइलर त्रुटि पाने के लिए यह कोड कुछ विधि के अंदर होना चाहिए ताकि numberLengthइस विधि का एक स्थानीय चर बन जाए ।
mykola

1
क्या कोई कारण है कि यह उदाहरण इतना जटिल क्यों है? कोड का अधिकांश भाग पूरी तरह से अप्रासंगिक रीजैक्स ऑपरेशन से क्यों निपट रहा है? और, जैसा कि @mykola ने पहले ही कहा था, यह प्रभावी अंतिम संपत्ति के संबंध में पूरी तरह से गायब है , क्योंकि यह केवल स्थानीय चर के लिए प्रासंगिक है और इस उदाहरण में कोई स्थानीय चर नहीं है।
होल्गर

131

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


4
यह सच है, जब तक कि जावा 8 के "फाइनल" की समझ अच्छी तरह से समझ में आती है। अन्यथा मैं एक ऐसे चर को देखूंगा जिसे अंतिम घोषित नहीं किया गया था जिसे आपने बाद में असाइन किया था, और त्रुटिपूर्ण रूप से लगता है कि यह अंतिम नहीं था। आप कह सकते हैं "बेशक" ... लेकिन हर कोई नवीनतम भाषा संस्करण परिवर्तनों पर उतना ध्यान नहीं देता जितना उन्हें चाहिए।
fool4jesus

8
इस नियम का एक अपवाद यह है कि एक स्थिरांक के साथ आरंभ किया गया एक स्थानीय चर संकलक के लिए एक स्थिर अभिव्यक्ति नहीं है। जब तक आप स्पष्ट रूप से अंतिम कीवर्ड नहीं जोड़ते हैं, तब तक आप स्विच / केस में इस तरह के चर का उपयोग नहीं कर सकते। जैसे "int k = 1; switch (someInt) {केस k: ..."।
हेन्नो वर्म्यूलेन

2
@HennoVermeulen स्विच-केस इस उत्तर में नियम का अपवाद नहीं है। भाषा निर्दिष्ट करती है कि case kएक स्थिर अभिव्यक्ति की आवश्यकता होती है जो एक स्थिर चर हो सकता है ("एक स्थिर चर आदिम प्रकार या प्रकार स्ट्रिंग का एक अंतिम चर है जो एक स्थिर अभिव्यक्ति के साथ प्रारंभ होता है" JLS 4.12.4 ) जो एक अंतिम का एक विशेष मामला है चर।
कॉलिन डी बेनेट

3
मेरे उदाहरण में कंपाइलर शिकायत करता है कि k एक स्थिर अभिव्यक्ति नहीं है इसलिए इसे स्विच के लिए उपयोग नहीं किया जा सकता है। अंतिम जोड़ते समय, संकलन व्यवहार बदल जाता है क्योंकि यह अब एक स्थिर चर है और इसे स्विच में उपयोग किया जा सकता है। तो आप सही हैं: नियम अभी भी सही है। यह केवल इस उदाहरण पर लागू नहीं होता है और यह नहीं कहता है कि k प्रभावी रूप से अंतिम है या नहीं।
हेनो वर्म्यूलेन

36

डॉक्स के अनुसार :

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

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

उदाहरण के लिए, कुछ वर्ग पर विचार करें:

public class Foo {

    public void baz(int bar) {
        // While the next line is commented, bar is effectively final
        // and while it is uncommented, the assignment means it is not
        // effectively final.

        // bar = 2;
    }
}

डॉक्स स्थानीय चर के बारे में बात करते हैं। barआपके उदाहरण में एक स्थानीय परिवर्तन नहीं है, लेकिन एक क्षेत्र है। त्रुटि संदेश में "प्रभावी रूप से अंतिम" जैसा कि ऊपर फ़ील्ड पर बिल्कुल भी लागू नहीं होता है।
अंती हापला

6
@AnttiHaapala barयहाँ एक पैरामीटर है, फ़ील्ड नहीं।
पीटर

30

'प्रभावी रूप से अंतिम' एक चर है जो संकलक त्रुटि नहीं देगा यदि इसे 'अंतिम' द्वारा जोड़ा जाना था

'ब्रायन गोएत्ज़' के एक लेख से,

अनौपचारिक रूप से, एक स्थानीय चर प्रभावी रूप से अंतिम है यदि इसका प्रारंभिक मूल्य कभी नहीं बदला गया है - दूसरे शब्दों में, इसे अंतिम घोषित करने से संकलन विफलता नहीं होगी।

लैम्ब्डा-राज्य-फाइनल- ब्रायन गोएत्ज़


2
यह उत्तर एक उद्धरण के रूप में दिखाया गया है, हालांकि ब्रायन के लेख में ऐसा कोई सटीक पाठ नहीं है, निश्चित रूप से इस शब्द को जोड़ा नहीं गया है । इसके बजाय यह एक उद्धरण है: अनौपचारिक रूप से, एक स्थानीय चर प्रभावी रूप से अंतिम है यदि इसका प्रारंभिक मूल्य कभी नहीं बदला गया है - दूसरे शब्दों में, इसे अंतिम घोषित करने से संकलन विफलता नहीं होगी।
lcfd

लेख शब्दशः प्रतिलिपि से: अनौपचारिक रूप से, एक स्थानीय चर प्रभावी रूप से अंतिम है यदि इसका प्रारंभिक मूल्य कभी नहीं बदला गया है - दूसरे शब्दों में, इसे अंतिम घोषित करना संकलन विफलता का कारण नहीं होगा।
अजीत गंगा

26

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

final int variable = 123;

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

int variable = 123;
variable = 456;

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

int variable = 123;

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


उत्तर जितना सरल होना चाहिए।
सुपरिग्नो

@ यूरिग, "सभी वेरिएबल्स डिफ़ॉल्ट रूप से अंतिम हैं" के लिए आवश्यक उद्धरण।
Pacerier

10

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

अंतिम :

final int number;
number = 23;

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

int number;
number = 34;

नोट : अंतिम और प्रभावी अंतिम समान हैं (असाइनमेंट के बाद उनका मूल्य परिवर्तित नहीं होता है) लेकिन केवल प्रभावी अंतिम चर कीवर्ड के साथ घोषित नहीं किए जाते हैं final


7

जब एक लंबोदर अभिव्यक्ति अपने संलग्न स्थान से एक निर्दिष्ट स्थानीय चर का उपयोग करता है तो एक महत्वपूर्ण प्रतिबंध होता है। एक लंबोदर अभिव्यक्ति केवल स्थानीय चर का उपयोग कर सकती है जिसका मूल्य नहीं बदलता है। उस प्रतिबंध को " वैरिएबल कैप्चर " के रूप में संदर्भित किया जाता है जिसे इस रूप में वर्णित किया गया है; लैम्ब्डा एक्सप्रेशन कैप्चर वैल्यू, वेरिएबल नहीं
लैंबडा अभिव्यक्ति का उपयोग करने वाले स्थानीय चर को " प्रभावी रूप से अंतिम " के रूप में जाना जाता है ।
एक प्रभावी रूप से अंतिम चर वह है जिसका मूल्य पहली बार दिए जाने के बाद नहीं बदलता है। ऐसे चर को अंतिम रूप से स्पष्ट रूप से घोषित करने की आवश्यकता नहीं है, हालांकि ऐसा करना एक त्रुटि नहीं होगी।
आइए इसे एक उदाहरण के साथ देखें, हमारे पास एक स्थानीय चर i है जिसे मूल्य 7 के साथ आरंभीकृत किया गया है, लैम्ब्डा अभिव्यक्ति में हम i को एक नया मान निर्दिष्ट करके उस मान को बदलने की कोशिश कर रहे हैं। इसके परिणामस्वरूप संकलक त्रुटि होगी - " एन्कोडिंग क्षेत्र में परिभाषित स्थानीय चर को अंतिम या प्रभावी रूप से अंतिम होना चाहिए "

@FunctionalInterface
interface IFuncInt {
    int func(int num1, int num2);
    public String toString();
}

public class LambdaVarDemo {

    public static void main(String[] args){             
        int i = 7;
        IFuncInt funcInt = (num1, num2) -> {
            i = num1 + num2;
            return i;
        };
    }   
}

2

प्रभावी अंतिम विषय जेएलएस 4.12.4 में वर्णित है और अंतिम पैराग्राफ में एक स्पष्ट विवरण है:

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


2

अंतिम कुंजी शब्द के साथ एक परिवर्तनीय घोषणा है final, उदाहरण:

final double pi = 3.14 ;

यह finalकार्यक्रम से बाहर रहता है ।

प्रभावी रूप से अंतिम : कोई भी स्थानीय चर या पैरामीटर जिसे केवल एक बार अभी (या केवल एक बार अपडेट किया गया) मान दिया जाता है। यह कार्यक्रम के माध्यम से प्रभावी रूप से अंतिम नहीं रह सकता है । तो इसका मतलब है कि प्रभावी रूप से अंतिम चर अपनी प्रभावी रूप से अंतिम संपत्ति को ढीला कर सकता है, जिसके तुरंत बाद इसे असाइन किया गया / कम से कम एक और असाइनमेंट अपडेट किया गया। उदाहरण:

class EffectivelyFinal {

    public static void main(String[] args) {
        calculate(124,53);
    }

    public static void calculate( int operand1, int operand2){   
     int rem = 0;  //   operand1, operand2 and rem are effectively final here
     rem = operand1%2  // rem lost its effectively final property here because it gets its second assignment 
                       // operand1, operand2 are still effectively final here 
        class operators{

            void setNum(){
                operand1 =   operand2%2;  // operand1 lost its effectively final property here because it gets its second assignment
            }

            int add(){
                return rem + operand2;  // does not compile because rem is not effectively final
            }
            int multiply(){
                return rem * operand1;  // does not compile because both rem and operand1 are not effectively final
            }
        }   
   }    
}

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

मेरी टिप्पणी में वर्णित सभी कारणों से उदाहरण कोड में टिप्पणियां गलत हैं। "प्रभावी रूप से अंतिम" एक राज्य नहीं है जो समय के साथ बदल सकता है।
एंड्रयूएफ

@AndrewF यदि यह समय के साथ नहीं बदलता है, तो आपको क्या लगता है कि अंतिम पंक्ति संकलित नहीं होती है? रेम गणना पद्धति में पंक्ति 1 पर प्रभावी रूप से अंतिम था। हालांकि, अंतिम पंक्ति पर, कंपाइलर शिकायत करता है कि रेम प्रभावी रूप से अंतिम नहीं है
वैज्ञानिक विधि

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

1
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; 

        }
    }    
}

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

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


1

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

लंबोदर भाव तक पहुँच सकते हैं

  • स्थिर चर,

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

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

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

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

साथ ही,

एक effectively finalचर वह चर है जिसका मूल्य कभी नहीं बदला जाता है, लेकिन यह finalकीवर्ड के साथ घोषित नहीं किया जाता है ।

स्रोत: जावा से शुरू करना: वस्तुओं (6 वें संस्करण), टोनी गद्दी के माध्यम से नियंत्रण संरचनाओं से

इसके अलावा, इसका अर्थ यह मत भूलो finalकि इसे पहली बार इस्तेमाल करने से पहले एक बार शुरू किया गया है।


0

एक वैरिएबल की घोषणा करना finalया इसे घोषित नहीं करना final, लेकिन इसे प्रभावी रूप से अंतिम रखने से परिणाम (कंपाइलर पर निर्भर करता है) अलग-अलग बायोटेक में हो सकता है।

एक छोटे से उदाहरण पर नजर डालते हैं:

    public static void main(String[] args) {
        final boolean i = true;   // 6  // final by declaration
        boolean j = true;         // 7  // effectively final

        if (i) {                  // 9
            System.out.println(i);// 10
        }
        if (!i) {                 // 12
            System.out.println(i);// 13
        }
        if (j) {                  // 15
            System.out.println(j);// 16
        }
        if (!j) {                 // 18
            System.out.println(j);// 19
        }
    }

mainविधि के संबंधित बाइटकोड (विंडोज़ 64 बिट पर जावा 8u161):

  public static void main(java.lang.String[]);
    Code:
       0: iconst_1
       1: istore_1
       2: iconst_1
       3: istore_2
       4: getstatic     #16                 // Field java/lang/System.out:Ljava/io/PrintStream;
       7: iconst_1
       8: invokevirtual #22                 // Method java/io/PrintStream.println:(Z)V
      11: iload_2
      12: ifeq          22
      15: getstatic     #16                 // Field java/lang/System.out:Ljava/io/PrintStream;
      18: iload_2
      19: invokevirtual #22                 // Method java/io/PrintStream.println:(Z)V
      22: iload_2
      23: ifne          33
      26: getstatic     #16                 // Field java/lang/System.out:Ljava/io/PrintStream;
      29: iload_2
      30: invokevirtual #22                 // Method java/io/PrintStream.println:(Z)V
      33: return

इसी पंक्ति संख्या तालिका:

 LineNumberTable:
   line 6: 0
   line 7: 2
   line 10: 4
   line 15: 11
   line 16: 15
   line 18: 22
   line 19: 26
   line 21: 33

हम लाइनों पर स्रोत कोड देख 12, 13, 14बाइट कोड में प्रकट नहीं होता। ऐसा इसलिए iहै क्योंकि trueयह राज्य है और नहीं बदलेगा। इस प्रकार यह कोड अप्राप्य है (इस उत्तर में अधिक )। इसी कारण से लाइन में कोड 9भी छूट जाता है। iयह trueसुनिश्चित करने के लिए नहीं है कि राज्य का मूल्यांकन किया जाना है ।

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


मैं इस संकलक अक्षमता पर विचार करूंगा, और जरूरी नहीं कि नए संकलक में भी ऐसा ही हो। एक परिपूर्ण संकलन में, यदि कोई चर प्रभावी रूप से अंतिम है, तो यह सभी सटीक समान अनुकूलन उत्पन्न करेगा, जैसे कि एक घोषित अंतिम। इसलिए इस धारणा पर भरोसा न करें कि कुछ अंतिम घोषित करने की तुलना में प्रभावी रूप से अंतिम स्वचालित रूप से धीमा है।
एंड्रयूएफ

@AndrewF आम तौर पर आप सही हैं, व्यवहार बदल सकता है। यही कारण है कि मैंने लिखा " परिणाम (संकलक पर निर्भर करता है) अलग-अलग बायोटेक में हो सकता है "। केवल लापता अनुकूलन (अलग-अलग बायोटेक) के कारण मैं निष्पादन को धीमा नहीं मानूंगा। लेकिन यह दिखाए गए मामले में अभी भी एक अंतर है।
ल्यूकियो

0

प्रभावी रूप से अंतिम चर एक स्थानीय चर है:

  1. के रूप में परिभाषित नहीं है final
  2. केवल एक बार सौंपा गया।

जबकि एक अंतिम चर एक चर है जो है:

  1. एक finalकीवर्ड के साथ घोषित किया गया ।

-6

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

यह जावा 8 पर शुरू नहीं हुआ, मैं लंबे समय से इसका उपयोग करता हूं। कानूनी होने के लिए (जावा 8 से पहले) इस कोड का उपयोग किया गया:

String str = ""; //<-- not accesible from anonymous classes implementation
final String strFin = ""; //<-- accesible 
button.addActionListener(new ActionListener() {
    @Override
    public void actionPerformed(ActionEvent e) {
         String ann = str; // <---- error, must be final (IDE's gives the hint);
         String ann = strFin; // <---- legal;
         String str = "legal statement on java 7,"
                +"Java 8 doesn't allow this, it thinks that I'm trying to use the str declared before the anonymous impl."; 
         //we are forced to use another name than str
    }
);

2
बयान इस तथ्य को संदर्भित करता है कि <जावा 8 में, केवल final चर को एक्सेस किया जा सकता है, लेकिन जावा 8 में भी वे प्रभावी रूप से अंतिम हैं।
अंती हापाला

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