java - जावा में स्टेटिक प्रारंभकर्ता




static static-initializer (6)

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

public class Test {
    private static final int a;    
    static {
        a = 5;
        doSomething(a);
    }
    private static int doSomething(int x) {
        return (x+5);
    }
}

यदि आप static कीवर्ड को हटाते हैं तो यह शिकायत करता है क्योंकि चर a final । हालांकि final और static दोनों कीवर्ड को निकालना और इसे संकलित करना संभव है।

यह मेरे लिए दोनों तरीकों से भ्रमित है। मुझे कोड कोड होना चाहिए जो किसी भी विधि से संबंधित नहीं है? इसे कैसे शुरू करना संभव है? आम तौर पर, इस उपयोग का उद्देश्य क्या है? या बेहतर, मैं इसके बारे में दस्तावेज कहां पा सकता हूं?


"अंतिम" गारंटी देता है कि ऑब्जेक्ट प्रारंभकर्ता कोड के अंत से पहले एक चर प्रारंभ किया जाना चाहिए। इसी प्रकार "स्थैतिक अंतिम" गारंटी देता है कि एक चर वैरिएबल प्रारंभिक कोड के अंत तक शुरू किया जाएगा। आपके प्रारंभिक कोड से "स्थिर" को छोड़कर इसे ऑब्जेक्ट प्रारंभिक कोड में बदल दिया जाता है; इस प्रकार आपका चर अब इसकी गारंटी को संतुष्ट नहीं करता है।


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

कक्षा लोड होने पर स्थिर चर प्रारंभ करने के लिए आप स्थैतिक प्रारंभकर्ता ब्लॉक लिख सकते हैं लेकिन यह कोड अधिक जटिल हो सकता है ..

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


यह सीधे http://www.programcreek.com/2011/10/java-class-instance-initializers/

1. निष्पादन आदेश

निम्न वर्ग को देखें, क्या आप जानते हैं कि पहले कौन सा निष्पादित हो जाता है?

public class Foo {

    //instance variable initializer
    String s = "abc";

    //constructor
    public Foo() {
        System.out.println("constructor called");
    }

    //static initializer
    static {
        System.out.println("static initializer called");
    }

    //instance initializer
    {
        System.out.println("instance initializer called");
    }

    public static void main(String[] args) {
        new Foo();
        new Foo();
    }
}

आउटपुट:

स्थिर प्रारंभिक कहा जाता है

उदाहरण प्रारंभकर्ता कहा जाता है

कन्स्ट्रक्टर कहा जाता है

उदाहरण प्रारंभकर्ता कहा जाता है

कन्स्ट्रक्टर कहा जाता है

2. जावा इंस्टेंस प्रारंभकर्ता कैसे काम करता है?

उपरोक्त उदाहरण प्रारंभकर्ता में एक println कथन शामिल है। यह समझने के लिए कि यह कैसे काम करता है, हम इसे एक चर असाइनमेंट कथन के रूप में देख सकते हैं, उदाहरण के लिए, b = 0 । यह समझने के लिए इसे और अधिक स्पष्ट कर सकता है।

के बजाय

int b = 0 , आप लिख सकते हैं

int b;
b = 0;

इसलिए, उदाहरण प्रारंभकर्ता और आवृत्ति चर प्रारंभकर्ता बहुत समान हैं।

3. उदाहरण प्रारंभकर्ता कब उपयोगी होते हैं?

इंस्टेंस प्रारंभकर्ताओं का उपयोग दुर्लभ है, लेकिन फिर भी यह आवृत्ति चर प्रारंभकर्ताओं के लिए एक उपयोगी विकल्प हो सकता है यदि:

  1. प्रारंभकर्ता कोड अपवादों को संभालना चाहिए
  2. गणना करें जो एक आवृत्ति चर प्रारंभकर्ता के साथ व्यक्त नहीं किया जा सकता है।

बेशक, इस तरह के कोड रचनाकारों में लिखा जा सकता है। लेकिन अगर एक वर्ग में कई रचनाकार थे, तो आपको प्रत्येक कन्स्ट्रक्टर में कोड दोहराना होगा।

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

एक और मामला जिसमें इंस्टेंस प्रारंभकर्ता उपयोगी हैं अज्ञात आंतरिक कक्षाएं हैं, जो कि किसी भी रचनाकार को घोषित नहीं कर सकती हैं। (क्या यह लॉगिंग फ़ंक्शन रखने के लिए एक अच्छी जगह होगी?)

Derhein के लिए धन्यवाद।

यह भी ध्यान रखें कि इंटरफेस को लागू करने वाले बेनामी वर्ग [1] में कोई कन्स्ट्रक्टर नहीं है। इसलिए निर्माण समय पर किसी प्रकार के अभिव्यक्ति निष्पादित करने के लिए इंस्टेंस प्रारंभकर्ताओं की आवश्यकता होती है।


स्थिर ब्लॉक की परिभाषा: जावा में स्टेटिक कीवर्ड

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

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

पीएस: आप आवृत्ति चर का उपयोग नहीं कर सकते हैं या स्थिर ब्लॉक के अंदर आवृत्ति विधियों का आह्वान नहीं कर सकते हैं।

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

public enum ErrorCodes {
    BUSINESS_ERROR(100), SERVER_ERROR(500), NETWORK_ERROR(1000);

    private int errorCode;
    // This field maps each error code numeric value to a corresponding Enum instance.
    private static Map<Integer, ErrorCodes> errorCodeByErrorNumber = new HashMap<Integer, ErrorCodes>();

    static {
        for (ErrorCodes errorCode : ErrorCodes.values()) {
            errorCodeByErrorNumber.put(errorCode.getErrorCode(), errorCode);
        }
    }

    private ErrorCodes(int errorCode) {
        this.errorCode = errorCode;
    }

    public int getErrorCode() {
        return errorCode;
    }

    public static ErrorCodes getErrorCodeByNumber(Integer dayNumber) {
        return errorCodeByErrorNumber.get(dayNumber);
    }
}

स्थैतिक कोड ब्लॉक का उपयोग कक्षा चर को त्वरित या प्रारंभ करने के लिए किया जा सकता है (ऑब्जेक्ट चर के विपरीत)। तो "ए" स्थैतिक साधनों को घोषित करना जो केवल सभी टेस्ट ऑब्जेक्ट्स द्वारा साझा किया जाता है, और स्थिर कोड ब्लॉक केवल एक बार "ए" शुरू करता है, जब टेस्ट क्लास पहली बार लोड होती है, भले ही कितनी टेस्ट ऑब्जेक्ट्स बनाई जाए।


static ब्लॉक एक "स्थैतिक प्रारंभकर्ता" है।

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

जेएनआई कोड लिखते समय मैंने व्यक्तिगत रूप से कभी इसका इस्तेमाल किया है:

class JNIGlue {
    static {
        System.loadLibrary("foo");
    }
}






static-initializer