2011-06-22 18 views
10

हूजाह!जावा एनम स्टेटिक फाइनल इंस्टेंस वैरिएबल

यह कोड एक समय के लिए काम करता था, फिर मैंने एक डिफ़ॉल्ट रंग जोड़ने का फैसला किया, और यह काम करना बंद कर दिया। मुझे निम्न त्रुटि मिलती है:

1 error found: 
File: Status.java [line: 20] 
Error: Status.java:20: illegal reference to static field from initializer 

संकलित समय पर निम्न कोड के साथ।

import java.awt.Color; 

enum Status 
{ 
    OFF ("Off"), 
    TRAINING ("Training", new Color(255, 191, 128)), 
    BEGINNER ("Beginner", new Color(128, 255, 138)), 
    INTERMEDIATE ("Intermediate", new Color(128, 212, 255)), 
    ADVANCED ("Advanced", new Color(255, 128, 128)); 

    public final String name; 
    public final Color color; 

    public static final Color defaultColor = Color.WHITE; 

    Status(String name) 
    { 
    this(name, defaultColor); 
    } 
    Status(String name, Color color) 
    { 
    this.name = name; 
    this.color = color; 
    } 
} 

यह काम करना चाहिए, जहां तक ​​मैं कह सकता हूं, लेकिन किसी भी कारण से जावा ने एक त्रुटि फेंकने का फैसला किया। कोई विचार?

+2

क्या 'डिफ़ॉल्ट रंग' फ़ील्ड रखने का कोई कारण है? क्या आपका शेष कोड अभी भी 'Status.color' को नहीं देख सकता है? –

उत्तर

23

defaultColor केवल प्रारंभ हो जाएगा के बाद कंस्ट्रक्टर्स बुलाया गया है - तो यह उस समय तक उसके डिफ़ॉल्ट मान (शून्य) होगा। एक विकल्प एक नेस्टेड प्रकार की डिफ़ॉल्ट रंग डाल करने के लिए होगा:

import java.awt.Color; 

enum Status 
{ 
    OFF ("Off"), 
    TRAINING ("Training", new Color(255, 191, 128)), 
    BEGINNER ("Beginner", new Color(128, 255, 138)), 
    INTERMEDIATE ("Intermediate", new Color(128, 212, 255)), 
    ADVANCED ("Advanced", new Color(255, 128, 128)); 

    public final String name; 
    public final Color color; 

    Status(String name) 
    { 
    this(name, Defaults.COLOR); 
    } 
    Status(String name, Color color) 
    { 
    this.name = name; 
    this.color = color; 
    } 

    private static class Defaults 
    { 
    private static Color COLOR = Color.WHITE; 
    } 
} 
बेशक

, यदि आप केवल कोड में एक बार डिफ़ॉल्ट रंग की चर्चा करते हुए रहे हैं, आप के साथ-साथ अंदर हार्ड कोड यह हो सकता है निर्माता कॉल:

Status(String name) 
{ 
    this(name, Color.WHITE); 
} 
10

enum स्थिरांक को पहले शुरू किया जाना है। उन्हें शुरू करने के लिए, रचनाकारों को बुलाया जाना चाहिए। पहला कन्स्ट्रक्टर एक स्थैतिक क्षेत्र का संदर्भ देता है जिसे संभवतः उस समय शुरू किया जा सकता था जब इसे कहा जाता है।

0
+0

आपके द्वारा लिंक की गई बग एनम क्लास के '.class' अक्षर का उपयोग करने के लिए है, न कि enum के वास्तविक स्थिर क्षेत्र का संदर्भ नहीं। – ColinD

+0

हां, लेकिन बाकी देखें। – MJB

6

जावा इस

class Status 
{ 
    public static final Status OFF = new Status("Off"); 

    public static final Color defaultColor = Color.WHITE; 

    Status(String name) 
    { 
     this(name, defaultColor); 
    } 
} 
बेशक

यह कार्यावधि में समस्या होगा की अनुमति देता है, लेकिन जावा परवाह नहीं है। यह init अनुक्रमों की व्यवस्था करने के लिए प्रोग्रामर का काम है, और कंपाइलर के लिए सभी टूटी हुई इनसाइट निर्भरताओं की जांच करना आसान नहीं है। समस्या वैसे भी ठीक करने के लिए आसान है:

class Status 
{ 
    // now it works, this field is initialized first 
    public static final Color defaultColor = Color.WHITE; 

    public static final Status OFF = new Status("Off"); 

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

यह प्रतिबंध आधा assed है। कन्स्ट्रक्टर से स्थैतिक क्षेत्रों के सभी संभावित उपयोगों को जांचना आसान नहीं है (यदि असंभव नहीं है)। निम्नलिखित कोड संकलित करेगा, प्रतिबंध को हरा देगा:

enum Status 
{ 
    OFF("Off"); 

    public static final Color defaultColor = Color.WHITE; 
    static Color defaultColor(){ return defaultColor; } 

    Status(String name) 
    { 
     this(name, defaultColor()); 
    } 
संबंधित मुद्दे