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


96

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

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

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

जवाबों:


113

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

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

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

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

static double a;
static double b = 1;

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

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

1
@GeorgeHawkins मैं केवल यह बताने की कोशिश कर रहा था कि इनलाइन इनिशियलाइज़र के बाद एक स्टैटिक इनिशियलाइज़र चलता है, ऐसा नहीं है कि एक समतुल्य इनलाइन नहीं किया जा सकता है। हालाँकि, मैं आपकी बात लेता हूँ और उदाहरण को (उम्मीद से) स्पष्ट किया है।
रिच ओ'केली

1
बस मज़े के लिए मैं यह बता सकता हूँ कि आपका पहला उदाहरण आसानी से "स्थिर डबल ए = someCondition; 0: 1" हो सकता है। ऐसा नहीं है कि आपके उदाहरण महान नहीं हैं, मैं सिर्फ कह रहा हूं ... :)
बिल K

18

एक विशिष्ट उपयोग:

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

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

आप इसे बिना स्टैटिक इनिशियलाइज़र के कैसे करेंगे?


2

2
अतिरिक्त पुस्तकालयों के बिना एक और जवाब: एक स्थैतिक विधि बनाएं SETजो चर आरंभीकरण का उपयोग करता है और चर आरंभीकरण ( private final static Set<String> SET = createValueSet()) का उपयोग करता है । यदि आपके पास 5 सेट और 2 मानचित्र हैं, तो क्या आप उन सभी को एक ही staticब्लॉक में डंप करेंगे ?
टीडब्लूआरआरओबी

16

आप static{}नीचे दिए गए प्रकार की कोशिश कर सकते हैं / नीचे ब्लॉक पकड़ सकते हैं :

MyCode{

    static Scanner input = new Scanner(System.in);
    static boolean flag = true;
    static int B = input.nextInt();
    static int H = input.nextInt();

    static{
        try{
            if(B <= 0 || H <= 0){
                flag = false;
                throw new Exception("Breadth and height must be positive");
            }
        }catch(Exception e){
            System.out.println(e);
        }

    }
}

पुनश्च: इस से संदर्भित !


12

आरंभीकरण के दौरान अपवाद संभालना एक और कारण है। उदाहरण के लिए:

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

यह उन निर्माणकर्ताओं के लिए उपयोगी है जो उपर्युक्त की तरह, जाँच किए गए अपवादों को खीझकर फेंक देते हैं, या फिर अधिक जटिल आरंभिक तर्क जो अपवाद-स्वरूप हो सकते हैं।


5

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


4

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


4

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


3

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

बेशक, मैं लगभग हमेशा अपने स्टैटिक्स बनाऊंगा finalऔर एक बेजोड़ वस्तु की ओर इशारा करूंगा ।


3

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

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

उदाहरण:

    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("=================");
    }
}

1

स्थैतिक कोड ब्लॉक, इंस्टक्शन से अधिक फ़ील्ड को आरम्भ करने में सक्षम बनाता है, घोषणाओं के एक अलग क्रम में फ़ील्ड को इनिशियलाइज़ करता है और सशर्त गहनता के लिए भी इस्तेमाल किया जा सकता है।

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

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घोषणा के नीचे आप घोषणा को स्थानांतरित कर सकते हैं b
गावी

1

हम अपने इंस्टेंस वेरिएबल्स (नॉन-स्टैटिक वेरिएबल्स, वैरिएबल्स जो ऑब्जेक्ट्स के हैं, क्लास के नहीं) को इनिशियलाइज़ करने के लिए कंस्ट्रक्टर्स का इस्तेमाल करते हैं।

यदि आप क्लास वेरिएबल्स (स्टैटिक वेरिएबल्स) को इनिशियलाइज़ करना चाहते हैं और ऑब्जेक्ट बनाए बिना इसे करना चाहते हैं (कंस्ट्रक्टर को केवल ऑब्जेक्ट बनाते समय ही कॉल किया जा सकता है), तो आपको स्टैटिक ब्लॉक की ज़रूरत है।

static Scanner input = new Scanner(System.in);
static int widht;
static int height;

static
{
    widht = input.nextInt();
    input.nextLine();
    height = input.nextInt();
    input.close();

    if ((widht < 0) || (height < 0))
    {
        System.out.println("java.lang.Exception: Width and height must be positive");
    }
    else
    {
        System.out.println("widht * height = " + widht * height);
    }
}

स्टैटिक इनिशियलाइज़र में स्टड पढ़ना एक बहुत ही भयानक विचार है। और System.out.println("B * H");बहुत बेकार है। और जवाब ही बहुत अस्पष्ट है। ओपी ने कंस्ट्रक्टरों या उदाहरण चर का उल्लेख नहीं किया।
shmosel

यह सिर्फ एक उदाहरण है जो दिखाता है कि एक स्टेटिक इनिशियलाइज़र क्या है और इसका उपयोग कैसे किया जाता है। ओपी ने निर्माणकर्ता या उदाहरण चर के लिए नहीं पूछा, लेकिन उसे निर्माणकर्ता से स्थिर इनिशियलाइज़र का अंतर सिखाने के लिए उसे यह जानना होगा। अन्यथा वह कहता है "मैं अपने स्थिर चर को शुरू करने के लिए सिर्फ एक निर्माता का उपयोग क्यों नहीं करता?"
माइकल

0

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


0

जब आप क्लास लोडिंग समय के दौरान किसी निश्चित अभिव्यक्ति का मूल्यांकन करना चाहते हैं तो आप स्टैटिक ब्लॉक का उपयोग कर सकते हैं लेकिन याद रखें:

आपको स्थैतिक ब्लॉक में एक अपवाद को संभालना होगा जिसका अर्थ है कि आप एक स्थिर ब्लॉक से अपवाद नहीं फेंक सकते।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.