2012-02-01 12 views
16

यह कोड संकलित नहीं होगा क्योंकि स्थिर क्षेत्र के लिए एक अवैध संदर्भ है।यह enum कोड एक स्थिर क्षेत्र के लिए एक अवैध संदर्भ क्यों है?

public enum Foo { 

    A, 
    B; 

    private Foo[] foos = new Foo[] { Foo.A }; 

} 

क्या आप एक गैर स्थैतिक क्षेत्र प्रारंभकर्ता से स्थिर फ़ील्ड तक पहुंचने में सक्षम नहीं होना चाहिए? उदाहरण के लिए:

public class Foo { 

    static int A; 

    private int[] foos = new int[] { Foo.A }; 

} 

यह ठीक संकलित करता है।

नोट, पहले उदाहरण संकलन में foos स्थिर बनाते हैं।

उत्तर

16

बाहर चेक जावा भाषा विशिष्टता, तीसरा संस्करण, http://java.sun.com/docs/books/jls/third_edition/html/classes.html#8.9

पर धारा 8.9 यह एक enum प्रकार कि एक संकलन समय स्थिर नहीं है की एक स्थिर क्षेत्र को संदर्भित करने के एक संकलन समय त्रुटि (§ है 15.28) रचनाकारों से, इंस्टेंस प्रारंभकर्ता ब्लॉक, या इंस्टेंस वेरिएबल प्रारंभकर्ता उस प्रकार के के भाव। यह कन्स्ट्रक्टर, इंस्टेंस प्रारंभकर्ता ब्लॉक, या इंस्टेंस वैरिएबल के लिए एक एनम निरंतर ई के प्रारंभिक अभिव्यक्ति अभिव्यक्तियों को स्वयं या ई के दाईं ओर घोषित किए गए उसी प्रकार के एक निरंतर स्थिरांक के लिए एक संकलित-समय त्रुटि है।

चर्चा

इस नियम के बिना, जाहिरा तौर पर उचित कोड आरंभीकरण घेरा enum प्रकार में निहित के कारण रन टाइम पर विफल हो जाएगा। (ए घेरा एक "आत्म टाइप किया" स्थिर क्षेत्र के साथ किसी भी वर्ग में मौजूद है।) यहाँ कोड की तरह का एक उदाहरण है कि विफल हो जाएगा है:

enum Color { 
     RED, GREEN, BLUE; 
     static final Map<String,Color> colorMap = 
     new HashMap<String,Color>(); 
     Color() { 
      colorMap.put(toString(), this); 
     } 
    } 

इस enum प्रकार के स्टेटिक आरंभीकरण NullPointerException फेंक देगा क्योंकि स्थैतिक परिवर्तनीय colorMap अनन्यकृत है जब enum स्थिरांक के लिए रचनाकार चलाते हैं। उपरोक्त प्रतिबंध सुनिश्चित करता है कि ऐसा कोड संकलित नहीं होगा।

7

एक बराबर, सरल तरीके से लिखा गया, बाइट कोड के करीब, हम देखते हैं:

public final class Foo { 
    public static final Foo A = new Foo(); 
    public static final Foo B = new Foo(); 

    private Foo[] foos; 

    private Foo() { 
     this.foos = new Foo[] { Foo.A }; 
    } 
} 

आप देख सकते A आरंभ करने के लिए हम निर्माता, जो A पढ़ता बुला रहे हैं। जाहिर है, जबकि अभी भी निर्माता A में प्रारंभ नहीं किया गया होगा।

(यह पता चला है के रूप में, यह सरल कोड संकलित करता है। यह सिर्फ तुम क्या उम्मीद कर सकते हैं नहीं करता है।)

आप शायद foos उदाहरण चर के बजाय Foo.values() चाहते हैं।

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