2012-02-21 19 views
38

क्या एक static ब्लॉक के भीतर प्रारंभ के बीच का अंतर है:जावा: एक स्थैतिक प्रारंभिक ब्लॉक कब उपयोगी होता है?

public class staticTest { 

    static String s; 
    static int n; 
    static double d; 

    static { 
     s = "I'm static"; 
     n = 500; 
     d = 4000.0001; 
    } 
    ... 

और व्यक्तिगत स्थिर प्रारंभ:

public class staticTest { 

    static String s = "I'm static"; 
    static int n = 500; 
    static double d = 4000.0001; 

    .... 
+1

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

+0

कक्षाएं लोड करने या मूल पुस्तकालय लोड करने के लिए यह एक अच्छी जगह है। – qrtt1

+0

ध्यान दें कि स्थैतिक चर से बचा जाना चाहिए और इसलिए स्थैतिक प्रारंभिक ब्लॉक आमतौर पर एक अच्छा विचार नहीं है। यदि आप स्वयं को बहुत उपयोग करते हैं, तो लाइन को कुछ परेशानी की उम्मीद करें। –

उत्तर

48

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

एक स्थिर प्रारंभ ब्लॉक भी इनलाइन स्थिर initializers के बाद चलता है, तो निम्नलिखित मान्य है:

static double a; 
static double b = 1; 

static { 
    a = b * 4; // Evaluates to 4 
} 
+1

"बी = ए * 4;" करना इनलाइन केवल एक समस्या होगी यदि बी को पहले घोषित किया गया था, जो आपके उदाहरण में नहीं है। –

+1

@ जॉर्ज हॉकिन्स मैं केवल यह कोशिश कर रहा था कि एक स्थिर प्रारंभिक इनलाइन प्रारंभकर्ताओं के बाद चलता है, न कि समकक्ष इनलाइन नहीं किया जा सका। हालांकि, मैं अपना मुद्दा लेता हूं और उदाहरण को अद्यतन करता हूं (उम्मीद है) स्पष्ट हो। –

+0

बस मस्ती के लिए मैं यह इंगित कर सकता हूं कि आपका पहला उदाहरण आसानी से "स्थिर डबल ए = कुछ कंडिशन? 0: 1;" ऐसा नहीं है कि आपके उदाहरण बहुत अच्छे नहीं हैं, मैं बस कह रहा हूं ... :) –

4

अपने उदाहरण में, कोई अंतर नहीं है; ,, लेकिन अक्सर प्रारंभिक मूल्य (या यह एक Method मौजूद नहीं हो सकता है कि, तो अपवाद-संचालकों की जरूरत है है जैसे, यह एक List<String> जिनकी सामग्री सबसे अच्छा एक for -loop द्वारा व्यक्त कर रहे हैं) की तुलना में आराम से एक भी अभिव्यक्ति में व्यक्त किया है और अधिक जटिल है और/या स्थिर फ़ील्ड को एक विशिष्ट क्रम में सेट करने की आवश्यकता है।

4

कभी कभी आप एक से अधिक सिर्फ स्थैतिक चर को मान निर्दिष्ट करना चाहते हैं। चूंकि आप कक्षा निकाय में मनमाने ढंग से बयान नहीं डाल सकते हैं, इसलिए आप एक स्थिर प्रारंभकर्ता ब्लॉक का उपयोग कर सकते हैं।

static double a; 
static { 
    if (SomeCondition) { 
     a = 0; 
    } else { 
     a = 1; 
    } 
} 

या जब सिर्फ निर्माण की तुलना में अधिक की जरूरत है:: जब एक बिल्डर का उपयोग कर अपने उदाहरण, अपवाद हैंडलिंग बना सकते हैं या बनाने के अलावा अन्य काम करने के लिए

3

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

बेशक

, मैं लगभग हमेशा एक unmodifiable वस्तु के लिए मेरे स्टैटिक्स final और बिंदु बनाने चाहते हैं।

12

एक ठेठ उपयोग:

private final static Set<String> SET = new HashSet<String>(); 

static { 
    SET.add("value1"); 
    SET.add("value2"); 
    SET.add("value3"); 
} 

आप इसे कैसे स्थिर प्रारंभकर्ता बिना करना होगा?

+2

उत्तर: [गुवा] (http://guava-libraries.googlecode.com/svn/trunk/javadoc/com/google/common/ संग्रह/ImmutableMap.Builder.html) :) +1 –

+0

@PaulBellora: पी – gawi

+0

अतिरिक्त पुस्तकालयों के बिना एक और उत्तर: एक स्थिर विधि बनाएं जो 'एसईटी' के प्रारंभिककरण को समाहित करती है और परिवर्तनीय प्रारंभकर्ता (' निजी अंतिम स्थैतिक सेट एसईटी = createValueSet() ')। क्या होगा यदि आपके पास 5 सेट और 2 मैप्स हैं, तो क्या आप उन्हें सभी को एक 'स्थिर' ब्लॉक में डंप करेंगे? – TWiStErRob

0

स्थिर कोड ब्लॉक, instuction की तुलना में अधिक के साथ खेतों को प्रारंभ घोषणाओं के भिन्न क्रम में खेतों प्रारंभ करने में सक्षम बनाता है और यह भी सशर्त intialization लिए इस्तेमाल किया जा सकता है। क्योंकि ए और बी अब के बाद घोषणा की जाती है

अधिक विशेष रूप से,

static final String ab = a+b; 
static final String a = "Hello,"; 
static final String b = ", world"; 

काम नहीं करेगा।

हालांकि मैं एक स्थिर init इस्तेमाल कर सकते हैं। इस पर काबू पाने के लिए ब्लॉक।

static final String ab; 
static final String a; 
static final String b; 

static { 
    b = ", world"; 
    a = "Hello"; 
    ab = a + b; 
} 

static final String ab; 
static final String a; 
static final String b; 

static { 
    b = (...) ? ", world" : ", universe"; 
    a = "Hello"; 
    ab = a + b; 
} 
+3

जबकि आप जो कह रहे हैं वह सच है, यह स्थिर प्रारंभकर्ता ब्लॉक की आवश्यकता का प्रदर्शन नहीं करता है। आप 'बी' की घोषणा के नीचे आपको 'ab' घोषणा को स्थानांतरित कर सकते हैं। – gawi

8

प्रारंभिकरण के दौरान अपवाद हैंडलिंग एक और कारण है। उदाहरण के लिए:

static URL url; 
static { 
    try { 
     url = new URL("https://blahblah.com"); 
    } 
    catch (MalformedURLException mue) { 
     //log exception or handle otherwise 
    } 
} 

यह कंस्ट्रक्टर्स कि annoyingly ऊपर की तरह, जांचे हुए अपवादों फेंक, वरना अधिक जटिल आरंभीकरण तर्क है कि अपवाद की आशंका वाले हो सकता है के लिए उपयोगी है।

4

static ब्लॉक प्रारंभ करने में सिंगलटन उदाहरण, सिंक्रनाइज़getInstance() विधि का उपयोग रोकने के लिए किया जा सकता है।

1

स्टेटिक कीवर्ड (चाहे वह एक चर या ब्लॉक है) कक्षा से संबंधित है। इसलिए जब कक्षा कहा जाता है, तो इन चर या ब्लॉक को निष्पादित किया जाता है। तो प्रारंभिक कीवर्ड की मदद से प्रारंभिकरण का अधिकांश हिस्सा किया जाएगा। चूंकि यह वर्ग से संबंधित है, वर्ग कक्षा का उदाहरण बनाये बिना सीधे इसे एक्सेस कर सकता है।

के एक उदाहरण लेते हैं, एक जूता वर्ग, जिसमें रंग, आकार, ब्रांड आदि जैसे कई चर देखते हैं नहीं है ... और यहाँ अगर जूता निर्माण कंपनी केवल एक ही ब्रांड है की तुलना में हम इसे आरंभ करना चाहिए स्थिर चर के रूप में। इसलिए, जूते के वर्ग को बुलाया जाता है और जूते के विभिन्न प्रकार पर निर्मित होते हैं (उस समय का रंग और आकार स्मृति पर कब्जा करेगा जब भी नया जूता बनाया गया है लेकिन यहां ब्रांड एक आम संपत्ति है सभी जूते, ताकि एक बार स्मृति के लिए स्मृति पर कब्जा कर सके चाहे कितने जूते निर्मित किए जाएं।

उदाहरण:

class Shoe { 
    int size; 
    String colour; 
    static String brand = "Nike"; 

    public Shoe(int size, String colour) { 
     super(); 
     this.size = size; 
     this.colour = colour; 
    } 

    void displayShoe() { 
     System.out.printf("%-2d %-8s %s %n",size,colour, brand); 
    } 

    public static void main(String args[]) { 
     Shoe s1 = new Shoe(7, "Blue"); 
     Shoe s2 = new Shoe(8, "White"); 

     System.out.println("================="); 
     s1.displayShoe(); 
     s2.displayShoe(); 
     System.out.println("================="); 
    } 
} 
0

एक स्थिर प्रारंभ ब्लॉक करता है, तो एक है, आपके द्वारा निर्दिष्ट वर्ग स्थिर प्रकार, वर्ग पहला प्रयोग करने से पहले intialize करना चाहते हैं उपयोगी है। बाद के उपयोग, किसी भी स्थिर प्रारंभिक ब्लॉक का आह्वान नहीं करेंगे। उदाहरण के प्रारंभकर्ताओं का सीधा विपरीत, जो इंस्टेंस सदस्यों को प्रारंभ करता है,

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