2015-06-11 16 views
11

के अज्ञात वर्ग के गैर-अंतिम वर्ग सदस्य का उपयोग क्यों कर सकता है हम जानते हैं कि अज्ञात वर्ग में केवल अंतिम स्थानीय चर का उपयोग किया जा सकता है, और यहां एक अच्छा कारण है: Why are only final variables accessible in anonymous class?गुमनाम वर्ग

हालांकि, मैंने पाया एक अनाम वर्ग अभी भी एक गैर अंतिम चर का उपयोग कर सकते हैं कि अगर चर संलग्नित क्लास के एक सदस्य क्षेत्र है: How can I access enclosing class instance variables from inside the anonymous class?

मैं उलझन में हूँ। हम सुनिश्चित करते हैं कि अज्ञात वर्ग में केवल एक अंतिम स्थानीय चर का उपयोग किया जा सके क्योंकि हम नहीं चाहते हैं कि चर अज्ञात वर्ग और स्थानीय फ़ंक्शन के बीच सिंक हो। यदि हम अज्ञात वर्ग में एक गैर-अंतिम संलग्न वर्ग सदस्य तक पहुंचने का प्रयास करते हैं तो वही कारण मामले पर लागू होना चाहिए।

यह चिंता क्यों नहीं होगी?

+0

'वही कारण केस पर लागू हो सकता है यदि हम अज्ञात वर्ग में गैर-अंतिम आवृत्ति चर का उपयोग करने का प्रयास करते हैं।' .... इसे किसी ऑब्जेक्ट के फ़ील्ड को इसके संदर्भ से एक्सेस करने के लिए कहा जाता है। ऑब्जेक्ट की उत्पत्ति या इसकी कक्षा की घोषणा क्यों होनी चाहिए? –

+0

@ user2499800: क्या आपने मेरा जवाब देखा है? आप इसके साथ कहाँ पहुंचे हैं? यदि आप उत्तर देते हैं तो सराहना करेंगे ... :) –

उत्तर

4

स्थानीय चर के मामले में, वैरिएबल के प्रतिलिपि अज्ञात वर्ग उदाहरण प्राप्त करता है। इस कारण से, अज्ञात वर्ग के भीतर इसका उपयोग करने से पहले स्थानीय चर को final बनाया जाना चाहिए, ताकि उसका मान बाद में परिवर्तित न हो।

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

मैं उलझन में हूं। हम सुनिश्चित करते हैं कि केवल अंतिम स्थानीय चर अज्ञात वर्ग में पहुंचा जा सकता है क्योंकि हम नहीं चाहते हैं कि परिवर्तनीय अज्ञात वर्ग और स्थानीय फ़ंक्शन के बीच सिंक हो। इसी कारण से मामले पर लागू होना चाहिए यदि हम अज्ञात वर्ग में कक्षा सदस्य संलग्न करने वाले गैर-अंतिम तक पहुंचने का प्रयास करते हैं।

जैसा कि आप देखते हैं, ऐसा नहीं है। प्रतिलिपि केवल स्थानीय चर के लिए होती है, न कि संलग्न वर्ग के सदस्य क्षेत्रों के लिए। कारण यह है कि एक अज्ञात वर्ग संलग्न वर्ग के लिए एक निहित संदर्भ रखता है, और उस संदर्भ के माध्यम से यह बाहरी वर्ग के किसी भी/सभी सदस्य फ़ील्ड & विधियों तक पहुंच सकता है। संलग्न वस्तु के जीवनकाल के दौरान

एक सदस्य चर मौजूद है, तो यह भीतरी वर्ग उदाहरण से संदर्भित हो सकते:

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

संदर्भ:

1.Why a non-final “local” variable cannot be used inside an inner class, and instead a non-final field of the enclosing class can?

+0

आप यह बताकर अपना जवाब सुधार सकते हैं कि प्रतिलिपि के बजाय संदर्भ का उपयोग करना क्यों संभव है। हालांकि यह स्पष्ट हो सकता है। – theMfromA

+0

राइटो, किया !!! –

+0

"इसके बजाय, अनाम वर्ग उदाहरण वास्तविक सदस्य फ़ील्ड का संदर्भ प्राप्त करता है।" नहीं। उनके पास केवल संलग्न उदाहरण का संदर्भ है। – newacct

2

गैर-स्टेटिक/इनर क्लास में उदाहरण संलग्न करने का संदर्भ है।इसलिए वे निश्चित रूप से आवृत्ति चर और विधियों का उल्लेख कर सकते हैं।

यदि यह पैरामीटर है, तो संलग्न वर्ग भी इसके बारे में कुछ नहीं जानता है, क्योंकि यह केवल उस विधि से सुलभ है जिसने इस चर को परिभाषित किया है।

तरह वाई.एस. पहले ही बताया:

एक स्थानीय चर के मामले में, चर की एक प्रति क्या गुमनाम वर्ग उदाहरण हो जाता है

+0

"गैर स्थैतिक आंतरिक कक्षाएं" एक ट्यूटोलॉजी है। यदि कक्षा स्थिर हैं और किसी अन्य वर्ग के भीतर घोषित की जाती है, तो उन्हें "स्थैतिक सदस्य वर्ग" कहा जाता है। यदि वे स्थैतिक नहीं हैं, तो उन्हें "आंतरिक कक्षाएं" कहा जाता है। –

+0

@EwinwinBolwidt: हाँ मैं स्लैश भूल गया। मैं वास्तव में गैर-स्टेटिक/आंतरिक कक्षाओं को लिखना चाहता था। उस संकेत के लिए धन्यवाद। –

1

यह अधिक दूसरी तरह के आसपास, एक स्थानीय चर रहा है है, x कहना अज्ञात उदाहरण के बाहर जब तक विधि कॉल होता है। इसका ऑब्जेक्ट संदर्भ कॉल स्टैक पर संग्रहीत है; ऑब्जेक्ट संदर्भ वाले स्टैक पर x == पता। x गुमनाम उदाहरण के अंदर एक कॉपी के रूप में अपनी जीवन भर, अलग लंबे समय तक या भी कम है।

वहाँ अब दो चर हैं, यह x (निराले ढंग से लागू करने के लिए) के लिए काम अनुमति देने के लिए नहीं करने का फैसला किया गया था और चर की आवश्यकता होने के लिए "प्रभावी रूप से अंतिम।"

एक बाहरी सदस्य के लिए प्रवेश, क्योंकि गुमनाम उदाहरण एक आंतरिक भी एक OuterClass.this संदर्भ युक्त वर्ग की है।

1

उदाहरण

class InnerSuper{ 
    void mInner(){} 
} 
class Outer{ 
    int aOuter=10; 
    InnerSuper mOuter(){ 
     int aLocal=3999; 
     class Inner extends InnerSuper{ 
      int aInner=20; 
      void mInner(){ 
       System.out.println("a Inner : "+aInner); 
       System.out.println("a local : "+aLocal); 
      } 
     } 
     Inner iob=new Inner(); 
     return iob; 
    } 
} 

class Demo{ 
    public static void main(String args[]){ 
     Outer ob=new Outer(); 
     InnerSuper iob=ob.mOuter(); 
     iob.mInner(); 
    } 
} 

यह जावा 1.8 या इसके बाद के संस्करण में किसी भी त्रुटि उत्पन्न नहीं करेगा निम्नलिखित पर विचार करें। लेकिन पिछले संस्करण में इस लिए कह स्पष्ट रूप से स्थानीय चर के रूप में अंतिम भीतरी वर्ग के भीतर पहुँचा घोषित करने के लिए एक त्रुटि उत्पन्न करता है। क्योंकि संकलक क्या करता है यह आंतरिक वर्ग द्वारा उपयोग की जाने वाली स्थानीय चर की एक प्रति रखेगा ताकि प्रतिलिपि मौजूद हो, भले ही विधि/ब्लॉक समाप्त हो और स्थानीय चर गुंजाइश से बाहर हो। यह घोषणा करने के लिए हमें पूछता है अंतिम चर स्थानीय भीतरी कक्षा के बाद गतिशील बाद में अपने मूल्य को परिवर्तित करता है कार्यक्रम में या गुमनाम वर्ग घोषित किया जाता है, प्रति संकलक द्वारा बनाई गई अपनी नई मूल्य के लिए परिवर्तन नहीं होगा क्योंकि और अनुमानित आउटपुट का उत्पादन न करके आंतरिक कक्षा के भीतर समस्याएं पैदा कर सकता है। इसलिए यह हमें स्पष्ट रूप से अंतिम घोषित करने की सलाह देता है।

लेकिन जावा 1.8 में यह एक त्रुटि उत्पन्न नहीं करेगा क्योंकि संकलक एक्सेस किए गए स्थानीय चर को अंतिम रूप से अंतिम घोषित करता है। यह जावा डॉक्स

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

मुझे समझाने दें कि प्रभावी रूप से अंतिम रूप से क्या मतलब है। उपरोक्त प्रोग्राम

class Outer{ 
    int aOuter=10; 
    InnerSuper mOuter(){ 
     int aLocal=3999; 
     class Inner extends InnerSuper{ 
      int aInner=20; 
      void mInner(){ 
       System.out.println("a Inner : "+aInner); 
       System.out.println("a local : "+aLocal); 
      } 
     } 
     aLocal=4000; 
     Inner iob=new Inner(); 
     return iob; 
    } 
} 

जावा में भी 1.8 में यह एक त्रुटि उत्पन्न करेगा। इसका कारण यह है alocal गतिशील कार्यक्रम के भीतर निर्दिष्ट किया जाए। इसका मतलब है कि परिवर्तक को प्रभावी ढंग से अंतिम संकलक द्वारा नहीं माना जा सकता है। क्या मैं संकलक समझ लिया है से के रूप में चर जो गतिशील रूप से अंतिम रूप में नहीं बदल रहे हैं की घोषणा की।इसे चर कहा जाता है प्रभावी रूप से अंतिम है।

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

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