2016-02-02 8 views
24

मैंने निम्न कोड लिखा है और सुपर क्लास के लिए ऑब्जेक्ट बनाया है।उप वर्ग 'स्थैतिक कोड निष्पादित क्यों किया जा रहा है?

class SuperClass{ 
    static int a=2; 
    static int b(){ 
     return 2; 
    } 
    int c(){ 
     return 2; 
    } 

    SuperClass(){ 
     System.out.println("Super"); 
    } 
    static { 
     System.out.println("super"); 
    } 
} 

public class Sub extends SuperClass{ 
    Sub(){ 
    System.out.println("Sub"); 
    } 
    static { 
     System.out.println("sub"); 
    } 
    static int b(){ 
     return 3; 
    } 
    int c(){ 
     return 3; 
    } 
    public static void main(String ax[]){ 
     SuperClass f =new SuperClass(); 
     System.out.println(f.c()); 
     System.out.print(SuperClass.b()); 
    } 
} 

जब मैं उत्पादन की जाँच की, यह इस प्रकार है:

super 
sub 
Super 
2 
2 

मुझे पता है कि स्थिर ब्लॉक केवल निष्पादित किया जाता है जब वर्ग की वस्तु आरंभ नहीं हो जाता या किसी स्थिर संदर्भ किया जाता है। लेकिन यहां, मैंने इनमें से कोई भी उप वर्ग में नहीं बनाया है। तो मैं "उप" यानी उप वर्ग 'स्थैतिक ब्लॉक आउटपुट क्यों देखूं?

+11

'मुख्य' विधि को निष्पादित करना (जो 'उप' वर्ग में घोंसला है) एक स्थिर संदर्भ है। :) –

+0

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

+3

@anil पहले नहीं, 'उप' वर्ग अभी भी' सुपर 'वर्ग पर निर्भर करता है, जिसे पहले निष्पादित किया जाता है। – njzk2

उत्तर

37

मुझे पता है कि स्थिर ब्लॉक केवल तभी निष्पादित किया जाता है जब कक्षा की वस्तु प्रारंभ होती है या कोई स्थिर संदर्भ बनाया जाता है। लेकिन यहां, मैंने इनमें से कोई भी उप वर्ग में नहीं बनाया है।

आपका कोड ऐसा नहीं करता है, लेकिन वह main के लिए चल सकता है जब, Sub लोड करने के लिए है। तो इसके लिए स्थिर प्रारंभकर्ता चलाया जाता है।

जैसे, मैं यह सोचते करती हूं कि आप इसे इस तरह भाग गया:

java Sub 

java उपकरण Sub लोड करने के लिए Sub.main कॉल करने के लिए है। यह स्थैतिक संदर्भ (पहुंच, वास्तव में) स्थिर प्रारंभिक चलाने के कारण होता है। (यदि आप इसे आईडीई में चलाते हैं, तो आईडीई java उपकरण भाग करेगा, लेकिन परिणाम वही है।)

तो यहाँ क्या हुआ है:

  1. java क्रम में Sub

  2. JVM SuperClass लोड करने के लिए है के लोड से चलाता है लोड करने के लिए Sub

  3. तो हम देखते हैं उनके स्थिर initializers चलाने के लिए, क्रम में (SuperClass, फिर Sub):

    कॉल f.c() में

    Super 
    
  4. कोड

    2 
    
  5. 0 में कोड:

    super 
    sub 
    
  6. java उपकरण main कॉल new SuperClass में कॉल main

  7. कोडकॉल SuperClass.b:

    2 
    

Holger काम आते हुए points out रूप में, यह §5.5 - Initialization में JVM विनिर्देश द्वारा कवर किया जाता है और संबंधित §5.2 - Java Virtual Machine Startup:

एक वर्ग के प्रारंभ या इंटरफ़ेस अपने वर्ग को क्रियान्वित करने के होते हैं या इंटरफेस प्रारंभिक विधि (§2.9)।

एक वर्ग या इंटरफ़ेस सी ही की वजह से प्रारंभ किया जा सकता है:

  • ...

  • तो सी एक वर्ग, अपने उपवर्गों में से एक के प्रारंभ है।

  • यदि सी कक्षा है, तो जावा वर्चुअल मशीन स्टार्टअप (§5.2) में प्रारंभिक कक्षा के रूप में इसका पदनाम।

दूसरे करने के लिए पिछले बुलेट बिंदु SuperClass को शामिल किया गया है कि, और पिछले बुलेट बिंदु Sub शामिल किया गया।

12

क्योंकि आपकी main() विधि Sub का सदस्य है, उस वर्ग को आपके प्रोग्राम चलाने के लिए लोड करने की आवश्यकता है।

9

main पर कॉल करने में, सभी स्थैतिक प्रारंभकर्ताओं को पहले सुपर क्लास में, फिर उप वर्ग में बुलाया जाता है।

जो आपके द्वारा देखे जाने वाले आउटपुट को बताता है।

3

क्लास लोड होने पर स्थिर ब्लॉक चलाए जाते हैं। आमतौर पर ऐसा इसलिए होता है क्योंकि आप एक कन्स्ट्रक्टर या स्थिर सदस्य कहते हैं। इस मामले में, ऐसा इसलिए है क्योंकि आपने मुख्य विधि (एक स्थिर सदस्य) निष्पादित किया है।

पक्ष नोट:

  1. एक और बढ़त मामले एक वर्ग लोड करने के लिए Class.forName (className) बुला रहा है।
  2. आप यह भी देख सकते हैं कि बेस क्लास सबक्लास से पहले लोड हो गया है।
संबंधित मुद्दे