स्थैतिक वर्ग आरंभीकरण कब होता है?


110

स्थैतिक क्षेत्र को कब आरंभ किया जाता है? यदि मैं कभी किसी क्लास को इंस्टेंट नहीं करता, लेकिन मैं एक स्टैटिक फील्ड को एक्सेस करता हूं, तो क्या सभी इंस्टेंट स्टॉक्स और प्राइवेट स्टैटिक मेथड्स का इस्तेमाल प्राइवेट इंस्ट्रूमेंट फिल्ड्स को करने के लिए किया जाता है?

यदि मैं एक स्थिर विधि कहूं तो क्या होगा? क्या यह सभी स्थिर ब्लॉकों को भी चलाता है? विधि से पहले?


स्थिर
इनिलाइज़र

जवाबों:


156

निम्न घटनाओं में से एक के पहली बार होने से तुरंत पहले एक वर्ग की स्थैतिक आरंभ सामान्य रूप से होती है:

  • कक्षा का एक उदाहरण बनाया जाता है,
  • कक्षा का एक स्थिर तरीका लागू किया जाता है,
  • कक्षा का एक स्थिर क्षेत्र सौंपा गया है,
  • एक गैर-स्थिर स्थिर फ़ील्ड का उपयोग किया जाता है, या
  • शीर्ष स्तर की कक्षा के लिए, कक्षा के भीतर निहित एक मुखर कथन को 1 निष्पादित किया जाता है

JLS 12.4.1 देखें ।

किसी वर्ग को प्रारंभ करने के लिए मजबूर करना संभव है (यदि यह पहले से ही आरंभिक नहीं है) Class.forName(fqn, true, classLoader)या संक्षिप्त रूप का उपयोग करकेClass.forName(fqn)


1 - अंतिम बुलेट बिंदु जावा 8 के लिए जावा 6 में मौजूद था, लेकिन यह स्पष्ट रूप से विनिर्देश में एक गलती थी। यह अंत में जावा 9 जेएलएस में सही किया गया था: स्रोत देखें ।


9
हालांकि एक आम नुकसान है। प्रिमिटिव और Stringएस को प्रतिस्थापित किया जाता है और संदर्भित नहीं किया जाता है। यदि आप class Other { public static final int VAL = 10; }किसी वर्ग से संदर्भ लेते हैं MyClass { private int = Other.VAL; }, तो कक्षा Otherलोड नहीं होगी। इसके बजाय, कंपाइलर संकलन के समय अंतिम क्षेत्र को बदल देगा।
राफेल विंटरथेलर

6
@ राफेलवर्थलटर - हां ... यह स्थिर स्थैतिक क्षेत्र का मामला है।
स्टीफन सी

2
@ राफेलवेन्थल्टर, यह सभी 'स्थिर अंतिम' आदिम या Stringचर के लिए सच नहीं है , केवल एक स्थिर अभिव्यक्ति द्वारा आरंभ किया गया है।
ल्यू बलोच

1
हां, और क्षेत्र को भी ऐसा करने की आवश्यकता नहीं है staticजबकि यह सामान्य मामला है।
राफेल विंटरथेलर

1
यह एक ही प्रोग्रामिंग भाषा है। हाँ।
स्टीफन सी

14

क्लास लोडिंग (लोडिंग, लिंकिंग और इनिशियलाइज़ेशन) के शुरुआती "चरण" के दौरान स्टेटिक फ़ील्ड्स को इनिशियलाइज़ किया जाता है , जिसमें स्टैटिक इनिशियलाइज़र्स और इसके स्टैटिक फ़ील्ड्स की इनिशियलाइज़ेशन शामिल होती हैं। स्थिर आरंभीकरण को एक पाठ क्रम में निष्पादित किया जाता है जैसा कि कक्षा में परिभाषित किया गया है।

उदाहरण पर विचार करें:

public class Test {

   static String sayHello()  {
      return a;
   }

   static String b = sayHello(); // a static method is called to assign value to b.
                                 // but its a has not been initialized yet.

   static String a = "hello";

   static String c = sayHello(); // assignes "hello" to variable c

    public static void main(String[] arg) throws Throwable {
         System.out.println(Test.b); // prints null
         System.out.println(Test.sayHello()); // prints "hello"
    }
}

Test.b प्रिंट करता है nullक्योंकि जब sayHelloस्टैटिक स्कोप में बुलाया गया था, तो स्टैटिक वेरिएबल aको इनिशियलाइज़ नहीं किया गया था।


6
सख्ती से बोलना, आरंभीकरण क्लास लोडिंग का "चरण" नहीं है। वास्तव में, कुछ वर्गों को लोड किया जा सकता है, लेकिन यदि आवेदन वास्तव में उनका उपयोग नहीं करता है, तो उन्हें प्रारंभिक नहीं किया जा सकता है।
स्टीफन C

@Stephen C आप सही हैं, मैंने इसे बेहतर शब्द की कमी के लिए इस्तेमाल किया है, शायद मैं इसे उद्धृत करूँगा।
naikus 5

@StephenC का मतलब यह है कि जब क्लास लोडिंग होती है, तो यह स्टैटिक वेरिएबल्स (और मेथड्स) को मेमोरी असाइन करता है, लेकिन उन स्टैटिक वेरिएबल्स को कोड में दिए गए वैल्यूज के साथ इनिशियलाइज़ नहीं किया जाता है? क्योंकि यहाँ यह प्रतीत होता है जब b-> sayHello () -> a, 'a' मेमोरी में है लेकिन इसका मान अभी तक असाइन नहीं किया गया है।
शब्बीर एस्साजी

असल में, हाँ।
स्टीफन सी

1

हां, पहली बार क्लास में पहुंचने से पहले सभी स्टैटिक इनिशियलाइज़र चलाए जाते हैं। अगर यह कोई और तरीका होता, तो मैं इसे बग कहता।


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