2015-12-16 5 views
6
class DemoClass { 
    public static void main(String args[]) { 
     System.out.println("Start"); 
     A a=new D(); 
    } 
} 
class A { 
    static { 
     System.out.println("Static A"); 
     A c=new C(); 
    } 

    public A() { 
     System.out.println("Constr A"); 
    } 
} 

class B extends A { 
    static { 
     System.out.println("Static B"); 
    } 

    public B() { 
     System.out.println("Constr B"); 
    } 
} 

class C extends B { 
    static { 
     System.out.println("Static C"); 
    } 

    public C() { 
     System.out.println("Constr C"); 
    } 
} 

class D extends C { 
    static { 
     System.out.println("Static D"); 
    } 

    public D() { 
     System.out.println("Constr D"); 
    } 
} 

ऊपर कोड के लिए निष्पादन का आदेश है:जब ऑब्जेक्ट बनाते समय जावा ब्लॉक में स्थिर ब्लॉक निष्पादित किया जाएगा?

Start 
Static A 
Constr A 
Constr B 
Constr C 
Static B 
Static C 
Static D 
Constr A 
Constr B 
Constr C 
Constr D 

मेरी नजर में सभी स्थैतिक ब्लॉक निष्पादित किया जाना चाहिए पहले तो केवल वस्तु बनाया जाएगा। लेकिन, यहां कक्षा "ए सी = नया सी()" कक्षा में एक स्थिर ब्लॉक पहले बनाया गया है और फिर अन्य स्थैतिक ब्लॉक निष्पादित किए जाते हैं। क्यूं कर?

+3

एक के रूप में अलग रूप में, मैं तुम्हें 3 वर्गों या संभवतः सिर्फ 2 बस के रूप में आसानी से के साथ इस प्रदर्शन किया जा सकता था संदेह है - और बनाया घटनाओं की एक व्यापक सूची प्रदान करना आसान है। –

उत्तर

13

सभी कक्षाओं के स्थिर प्रारंभकर्ता ने निष्पादन शुरू किया - लेकिन डी, सी शुरू करने के लिए प्रारंभ किया जाना चाहिए, इसलिए बी प्रारंभ किया जाना चाहिए, इसलिए ए प्रारंभ किया जाना चाहिए। बिंदु जहां A में स्थिर प्रारंभकर्ता में कोड निष्पादित की जा रही है पर, शामिल कक्षाओं के सभी "प्रारंभ किया जा रहा" के एक राज्य में कर रहे हैं।

A के स्थिर प्रारंभकर्ता के भीतर, यह C का एक उदाहरण का निर्माण करती है - लेकिन Cपहले से ही प्रारंभ किया जा रहा है, तो प्रारंभकर्ता फिर से शुरू नहीं करता है है ... JVM सिर्फ नोट (भीतर है कि यह पहले से ही प्रारंभ किया जा रहा है एक ही धागा) और जारी है।

इस सब के विवरण JLS 12.4.2 में हैं। विशेष रूप से, गोली:

C के लिए Class वस्तु इंगित करता है कि प्रारंभ वर्तमान धागा द्वारा सी के लिए कार्य प्रगति पर है, तो यह प्रारंभ के लिए एक पुनरावर्ती अनुरोध किया जाना चाहिए। LC रिलीज करें और सामान्य रूप से पूर्ण करें।

और

इसके बाद, यदि सी एक वर्ग के बजाय एक अंतरफलक, और उसके सुपर क्लास अभी तक प्रारंभ नहीं किया गया है, तो अनुसूचित जाति अपने सुपर क्लास रहने दो और SI1, ..., पाप रहने दो सी के सभी superinterfaces जो कम से कम एक डिफ़ॉल्ट विधि घोषित करते हैं। [...]

प्रत्येक के लिए सूची में एस [अनुसूचित जाति, SI1, ..., पाप], रिकर्सिवली इस पूरे प्रक्रिया एस के लिए यदि आवश्यक हो, प्रदर्शन को सत्यापित करने और पहले एस तैयार करते हैं।

... प्रासंगिक हैं।

+0

मैं "स्टेटिक बी" से पहले "कॉन्स्ट्रर बी" पर परेशान हूं। क्या आपके पास कोई सुझाव है? – Mikey

+1

@ माइकी: यह बिल्कुल वही है - यह सी बनाने का हिस्सा है, जो तब होता है जब ए के लिए स्थैतिक प्रारंभकर्ता का * बॉडी * निष्पादित होता है। –

-2
..

जब JVM उस समय सभी स्थैतिक सदस्य स्कैन किया जाएगा और स्मृति उनके लिए आवंटित किया जाएगा पर आरंभ करने के लिए तो यह कोई स्थिर के लिए जाना होगा

इसलिए पहले यह प्रिंट होगा स्थिर तो गैर स्थिर

+0

मुझे नहीं लगता कि आपने प्रश्न को सावधानीपूर्वक पढ़ लिया है। –

5

@JonSkeet तकनीकी शब्दों में सब कुछ कहा है और मुझे लगता है कि अधिक से अधिक नहीं कह सकता। मुझे एक समानता का उपयोग करके व्याख्या करने की कोशिश करें:

कमरे के दरवाजे खोलने और उस कमरे में कन्स्ट्रक्टर निष्पादन के रूप में कन्स्ट्रक्टर निष्पादन के रूप में स्थिर प्रारंभिकरण के बारे में सोचें।

अब, कमरे के दरवाजे को खोलने के लिए आपको सी के दरवाजे खोलने की जरूरत है, सी के लिए आपको बी की आवश्यकता है और बी के लिए आपको ए की जरूरत है। अब, आप कमरे ए में हैं और आपके पास कमरे ए में दरवाजा खोलने की औपचारिकताएं हैं। और जब कक्ष एक में दरवाजा खोलने औपचारिकताओं परिष्करण, आप एक नोट उस कमरे सी (A c=new C();) का काम खत्म देखते हैं। अब चूंकि कमरा सी और इसके आश्रित कमरे पहले ही खुले हैं, आपको फिर से खोलने की आवश्यकता नहीं है (इसका मतलब है कि कोई स्थिर ब्लॉक प्रारंभिकरण नहीं है)।लेकिन इससे पहले कि आप कमरे सेल्सियस के लिए जाना आप कंसोल में, कमरे में एक उद्घाटन औपचारिकताओं यानी System.out.println("Static A"); तो खत्म हो जाएगा आप:

स्टेटिक एक

अब, आप कमरे सी में हैं और आप समाप्त करने के लिए है इस कमरे में लेकिन इससे पहले कि आप निर्भरता के कारण बी और ए खत्म कर चुके हैं (सी बी और बी बढ़ाता है ए)। तो, कंसोल में आप:

कंस्ट्रक्शन कंपनी एक कंस्ट्रक्शन कंपनी बी कंस्ट्रक्शन सी

अब, आप फिर से वापस कमरे में एक के पास जाकर देखने के लिए दरवाजा खोलने औपचारिकताएं पूरा कर लें होगा। तो, आप कक्ष बी तो सी और फिर डी तो करने के लिए आ जाएगा, कंसोल में आप:

स्टेटिक बी स्टेटिक सी स्टेटिक डी

कमरे से अब, आप खत्म कर रहे हैं काम डी (A a=new D();) और ऐसा करने के लिए आपको निर्भरता की वजह से सी, बी और सी का काम खत्म करने की आवश्यकता है (डी विस्तारित करता है, सी विस्तारित बी और बी विस्तारित करता है ए)। तो, कंसोल में आप:

कंस्ट्रक्शन कंपनी एक कंस्ट्रक्शन कंपनी बी कंस्ट्रक्शन सी कंस्ट्रक्शन कंपनी डी

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