यह सोचना एक आम भ्रांति है कि एक स्थिर ब्लॉक में केवल स्थिर क्षेत्रों तक ही पहुंच होती है। इसके लिए मैं नीचे दिए गए कोड ऑफ कोड दिखाना चाहूंगा जो मैं अक्सर वास्तविक जीवन की परियोजनाओं में उपयोग करता हूं ( थोड़े अलग संदर्भ में दूसरे उत्तर से आंशिक रूप से कॉपी किया गया ):
public enum Language {
ENGLISH("eng", "en", "en_GB", "en_US"),
GERMAN("de", "ge"),
CROATIAN("hr", "cro"),
RUSSIAN("ru"),
BELGIAN("be",";-)");
static final private Map<String,Language> ALIAS_MAP = new HashMap<String,Language>();
static {
for (Language l:Language.values()) {
// ignoring the case by normalizing to uppercase
ALIAS_MAP.put(l.name().toUpperCase(),l);
for (String alias:l.aliases) ALIAS_MAP.put(alias.toUpperCase(),l);
}
}
static public boolean has(String value) {
// ignoring the case by normalizing to uppercase
return ALIAS_MAP.containsKey(value.toUpper());
}
static public Language fromString(String value) {
if (value == null) throw new NullPointerException("alias null");
Language l = ALIAS_MAP.get(value);
if (l == null) throw new IllegalArgumentException("Not an alias: "+value);
return l;
}
private List<String> aliases;
private Language(String... aliases) {
this.aliases = Arrays.asList(aliases);
}
}
यहाँ इनिशलाइज़र का उपयोग इंडेक्स ( ALIAS_MAP
) को बनाए रखने के लिए किया जाता है , जिससे एलियम का एक सेट मूल एनुम प्रकार पर वापस आ सके। यह Enum
स्वयं के द्वारा प्रदान की गई अंतर्निहित वैल्यूऑफ पद्धति के विस्तार के रूप में करना है।
जैसा कि आप देख सकते हैं, स्टैटिक इनिशियलाइज़र private
क्षेत्र में भी पहुँचता है aliases
। यह समझना महत्वपूर्ण है कि static
ब्लॉक में पहले से ही Enum
मूल्य उदाहरणों (जैसे ENGLISH
) तक पहुंच है । ऐसा इसलिए है क्योंकि प्रकारों के मामले में आरंभीकरण और निष्पादन का क्रमEnum
, जैसे static private
कि static
ब्लॉकों को उदाहरणों से पहले उदाहरणों से आरम्भ किया गया है:
Enum
स्थिरांक जो निहित स्थिर क्षेत्र हैं। इसके लिए Enum कंस्ट्रक्टर और उदाहरण ब्लॉक की आवश्यकता होती है, और उदाहरण इनिशियलाइज़ेशन पहले भी होता है।
static
घटना के क्रम में स्थिर क्षेत्रों के ब्लॉक और आरंभीकरण।
यह आउट-ऑफ-ऑर्डर आरंभीकरण ( static
ब्लॉक से पहले निर्माणकर्ता ) नोट करने के लिए महत्वपूर्ण है। यह तब भी होता है जब हम एक सिंगलटन (उदाहरण के लिए बनाए गए) जैसे उदाहरणों के साथ स्थैतिक क्षेत्रों को आरंभ करते हैं:
public class Foo {
static { System.out.println("Static Block 1"); }
public static final Foo FOO = new Foo();
static { System.out.println("Static Block 2"); }
public Foo() { System.out.println("Constructor"); }
static public void main(String p[]) {
System.out.println("In Main");
new Foo();
}
}
हम जो देखते हैं वह निम्न आउटपुट है:
Static Block 1
Constructor
Static Block 2
In Main
Constructor
स्पष्ट है कि स्थिर आरंभीकरण वास्तव में कंस्ट्रक्टर से पहले हो सकता है , और उसके बाद भी:
बस मुख्य विधि में फू तक पहुँचने, वर्ग लोड होने का कारण बनता है और स्थैतिक आरंभीकरण शुरू होता है। लेकिन स्टेटिक इनिशियलाइज़ेशन के एक भाग के रूप में हम फिर से स्टैटिक फ़ील्ड्स के लिए कंस्ट्रक्टरों को कॉल करते हैं, जिसके बाद यह स्टैटिक इनिशियलाइज़ेशन को फिर से शुरू करता है, और मेन मेथड के भीतर से बुलाए गए कंस्ट्रक्टर को पूरा करता है। इसके बजाय जटिल स्थिति जिसके लिए मुझे उम्मीद है कि सामान्य कोडिंग में हमें निपटना नहीं होगा।
इस बारे में अधिक जानकारी के लिए " प्रभावी जावा " पुस्तक देखें ।
{...}
बनाम के बीच का अंतर पता हैstatic {...}
। (किस मामले में जॉन स्कीट ने निश्चित रूप से आपके प्रश्न का उत्तर बेहतर तरीके से दिया)