2015-02-09 10 views
18

जावा 7 कह रहे थे निम्नलिखित कोड पर "गैर अंतिम स्थानीय चर संदेश एक enclosing दायरे में परिभाषित करने का उल्लेख नहीं कर सकते":जावा इनर क्लासों में गैर अंतिम चर पर erroring (जावा 8) बंद कर दिया

public class Runner { 
    public static void main(String[] args) { 

     String message = "Hello world"; 

     new Runnable() { 
      @Override 
      public void run() { 
       System.out.println(message); 
      } 
     }.run(); 
    } 
} 

जावा 8 नहीं करता है।

संदेह यह जावा पर कार्यात्मक प्रोग्रामिंग सुविधाओं को जोड़ने के बारे में है।

क्या यह कोड को इसी तरह संसाधित करता है?

+0

बहुत रोचक। – vikingsteve

उत्तर

23

जावा 8 स्पष्ट रूप से message फ़ाइनल बनाता है क्योंकि इसे कभी संशोधित नहीं किया जाता है। इसे अपने कोड में कहीं भी संशोधित करने का प्रयास करें और आपको एक संकलन त्रुटि मिलेगी (क्योंकि इससे अंतर्निहित final) हटा दिया जाता है।

इसे प्रभावी रूप से अंतिम कहा जाता है। From the docs का हवाला देते हुए:

However, starting in Java SE 8, a local class can access local variables and parameters of the enclosing block that are final or effectively final. A variable or parameter whose value is never changed after it is initialized is effectively final.

+0

जैसे ही आप इसे कहीं भी संशोधित करेंगे (रननेबल के बाहर भी) आपको एक त्रुटि मिलेगी? – gfkri

+0

हाँ, यह सही है। इसे अदृश्य 'अंतिम' के रूप में सोचें। – Matt

7

जावा 8 (और lambdas) परिचय प्रभावी ढंग से अंतिम अवधि:, भले ही आप इसे final कीवर्ड के साथ अंतिम delcare नहीं था अगर यह संशोधित नहीं है, यह अंतिम के रूप में अच्छा है ।

Oracle Tutorial: Local Classes से हवाला देते हुए:

However, starting in Java SE 8, a local class can access local variables and parameters of the enclosing block that are final or effectively final. A variable or parameter whose value is never changed after it is initialized is effectively final.

आपका संदेश प्रभावी ढंग से अंतिम है, इसलिए यह गुमनाम भीतरी वर्गों और lambdas से यह उल्लेख करने के लिए मान्य है।

आप संदेश का मूल्य बदलते हैं, तो यह नहीं होगा प्रभावी ढंग से अंतिम अब:

String message = "Hello world"; 
new Runnable() { 
    @Override 
    public void run() { 
     System.out.println(message); 
    } 
}.run(); 
message = "modified"; 

और इसलिए आपको निम्न त्रुटि (ग्रहण से) मिलती है:

Local variable message defined in an enclosing scope must be final or effectively final

या फॉर्म javac:

error: local variables referenced from an inner class must be final or effectively final

2

परिवर्तनीय messageeffectively final है। , भाषा संदर्भ

If a variable is effectively final, adding the final modifier to its declaration will not introduce any compile-time errors.

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

यह त्रुटि फेंक दिया है |:

new Runnable() { 
      @Override 
      public void run() { 
       message = "hey"; 
       System.out.println(message); 
      } 
     }.run(); 

कारण java7 संकलक फेंकता त्रुटि lambdas के लिए एक युक्ति परिवर्तन के कारण है।

Any local variable, formal parameter, or exception parameter used but not Any local variable, formal parameter, or exception parameter used but not declared in a lambda expression must either be declared final or be effectively final (§4.12.4), or a compile-time error occurs where the use is attempted.

बेनामी इनर क्लासेस और लैम्बडा एक ही नियम साझा करते हैं।

2

हां, यह तरह है।

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

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

+0

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

+0

@ मार्कोटोपोलनिक आप सही हैं, उन्हें क्या एहसास हुआ है कि वे उस पर भरोसा कर सकते हैं और डेवलपर्स को 'अंतिम' कीवर्ड जोड़ने के लिए मजबूर करने का कोई कारण नहीं है। लेकिन जवाब उन्हें पहले दिन से चेहरे पर देख रहा था। – biziclop

संबंधित मुद्दे