2011-12-09 17 views
16

के साथ व्यवहार्य मैंने एक निजी सदस्य चर के साथ एक enum बनाया है। जब मैं सदस्य चर का उपयोग करने का प्रयास करता हूं तो संकलित करता है 'गैर स्थैतिक क्षेत्र सदस्य के लिए स्थिर संदर्भ नहीं बना सकता'।गैर-स्थैतिक फ़ील्ड सदस्य के लिए स्थिर संदर्भ नहीं बना सकता है निजी चर

यदि चर निजी नहीं है (उदा। संरक्षित या पैकेज सुरक्षित है) यह ठीक से संकलित करता है। मुझे समझ में नहीं आता है कि परिवर्तनीय के दायरे को लागू अमूर्त फ़ंक्शन के प्रकार (स्थैतिक, गैर स्थैतिक) के साथ क्या करना है।

क्या कोई मुझे प्रबुद्ध कर सकता है?

public enum EnumWithAbstractMethodAndMembers { 
    TheOneAndOnly(1) { 
     @Override 
     public int addValue(final int value) { 
      return memberVariable + value; 
     } 
    }; 

    private final int memberVariable; 

    private EnumWithAbstractMethodAndMembers(final int memberVariable) { 
     this.memberVariable = memberVariable; 
    } 

    abstract int addValue(int value); 

} 

उत्तर

19

त्रुटि संदेश भ्रमित है।

समस्या यह है कि जब आप enum मान कोड देते हैं, तो आप enum का एक अनाम उप वर्ग बना रहे हैं। (इसकी कक्षा EnumWithAbstractMethodAndMembers$1 होगी) एक उप-वर्ग अपने सुपर-क्लास के निजी सदस्यों तक नहीं पहुंच सकता है, हालांकि घोंसला वाले वर्ग जेनरेट किए गए एक्सेसर विधि के माध्यम से कर सकते हैं। आपको निजी क्षेत्र तक पहुंचने में सक्षम होना चाहिए, और यह त्रुटि संदेश देता है जो आपको गलत-अग्रणी प्रतीत होता है।

बीटीडब्ल्यू आप इसका उपयोग कर सकते हैं, लेकिन आपको IMHO की आवश्यकता नहीं है।

public int addValue(final int value) { 
     return super.memberVariable + value; 
    } 

यहाँ मैं त्रुटि संदेश में एक बग के रूप में प्रवेश करेंगे एक छोटा उदाहरण के रूप में यह समस्या का समाधान करने के लिए नेतृत्व नहीं करता है।

public enum MyEnum { 
    One { 
     public int getMemberVariableFailes() { 
      // error: non-static variable memberVariable cannot be referenced from a static context 
      return memberVariable; 
     } 

     public int getMemberVariable2OK() { 
      return memberVariable2; 
     } 

     public int getMemberVariableOK() { 
      return super.memberVariable; 
     } 
    }; 

    private final int memberVariable = 1; 
    final int memberVariable2 = 1; 
} 

टॉम Hawkin की प्रतिक्रिया के आधार पर, इस उदाहरण में एक ही त्रुटि संदेश हो जाता है।

public class MyNotEnum { 
    // this is the static context in which the anonymous is created 
    public static final MyNotEnum One = new MyNotEnum() { 
     public int getMemberVariableFailes() { 
      // error: non-static variable memberVariable cannot be referenced from a static context 
      return memberVariable; 
     } 

     public int getMemberVariableOK() { 
      return super.memberVariable; 
     } 
    }; 
    private final int memberVariable = 1; 
} 

तुलना

public class MyNotEnum { 
    public class NestedNotEnum extends MyNotEnum { 
     public int getMemberVariableFailes() { 
      // compiles just fine. 
      return memberVariable; 
     } 

     public int getMemberVariableOK() { 
      return super.memberVariable; 
     } 
    } 
    private final int memberVariable = 1; 
} 
+0

ध्वनि का उचित। जवाब के लिए Thx और 'सुपर' के साथ संकेत! – Andreas

+0

मैंने इसे 'javac' बग के रूप में लॉग किया है। –

+1

वे कहते हैं कि यह कुछ दिनों में दिखाई देना चाहिए। http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=7119746 मैंने देखा है कि ओरेकल ने मेरी बग्स को स्वीकार किया ** ** ** सूर्य की तुलना में तेज़ ** तेज है। –

0

त्रुटि का मुख्य कारण के लिए है: आप आंतरिक कार्यान्वयन वर्ग से सुपर वर्ग के निजी चर (memberVariable) के संदर्भ में बनाने की कोशिश कर रहे हैं।

  • आप memberVariable के बाद से super.memberVariable उपयोग करने के लिए है नहीं स्थानीय
  • TheOnlyAndOnly() करने के लिए आप int memberVariableसार्वजनिक बना सकते हैं:

    त्रुटि मुक्त कोड आप निम्न में से या तो कर सकते हैं बनाने के लिए।

  • आप कर सकते हैं:

    TheOneAndOnly(1) { 
        int memberVariable=4; 
        @Override 
        public int addValue(final int value) { 
         return memberVariable + value; 
        } 
    }; 
    
3

ऐसा ही एक मुद्दा (मैं नहीं जानता कि जहाँ मेरे प्रतियों की या तो है, इसलिए मैं नहीं कर सकता जोश बलोच और नील Gafter द्वारा जावा पहेलियों में कवर किया जाता है आपको एक सटीक संदर्भ दें)।

यह enums के बारे में कुछ खास नहीं है। एक स्थिर संदर्भ में कोई भी अज्ञात (या स्थानीय) आंतरिक वर्ग करेगा। नियम यह है कि बाहरी वर्ग को सुपर क्लास के समक्ष माना जाता है। यह गैर-स्थैतिक संदर्भ में ऐसी कक्षाओं के लिए बहुत अधिक समझ में आता है।यदि स्थैतिक परिवर्तन को संदर्भित किया गया है, तो किस चर को देखा गया था, रनटाइम पर "भ्रम" पेश करने की क्षमता है (सी ++ इस तरह के नियम के साथ अधिक आक्रामक है)।

बाहरी कक्षा के विस्तार वाले एक आंतरिक वर्ग में बाहरी वर्ग के निजी उदाहरण फ़ील्ड तक पहुंच है, चाहे this या किसी अन्य उदाहरण के माध्यम से।

जैसा कि हमें पहुंच की अनुमति है, हमें किसी भी तरह से निर्दिष्ट करने की आवश्यकता है कि हम इसे बाहरी के बजाय अंदर से जाना चाहते हैं। जैसा कि पीटर लॉरी super.member बताते हैं। आप भी इस भीतरी चयन कर सकते हैं, और फिर उस अभिव्यक्ति का उपयोग:

 return ((EnumWithAbstractMethodAndMembers)this).memberVariable + value; 

या

 EnumWithAbstractMethodAndMembers innerThis = this; 
     return innerThis.memberVariable + value; 
संबंधित मुद्दे