2015-01-13 9 views
11

के लिए नहीं बुलाया गया है निम्न जावा कोड कक्षा B के स्थिर प्रारंभकर्ता का आह्वान नहीं करता है। क्यूं कर?स्टेटिक प्रारंभकर्ता को व्युत्पन्न कक्षा

कोड:

class A 
{ 
    static 
    { 
     System.out.println("A static init"); 
    } 

    public static void f() 
    { 
     System.out.println("f() called"); 
    } 
} 

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

public class App 
{ 
    public static void main(String[] args) 
    { 
     B.f(); //invokestatic #16     // Method com/db/test/B.f:()V 
    } 
} 

कार्यक्रम उत्पादन:

A static init 
f() called 

JDK 1.8.0_25 पर परीक्षण किया गया

+1

संभवतः http://stackoverflow.com/questions/13475172/java-static-initialization-with-inheritance – h7r

उत्तर

13

"स्थिर निर्माता" के रूप में ऐसी कोई चीज नहीं है। यह एक स्थिर प्रारंभिक ब्लॉक है, और इसे केवल तभी निष्पादित किया जाता है जब वर्ग प्रारंभ होता है। चूंकि आप कक्षा ए की स्थैतिक विधि को कॉल कर रहे हैं (भले ही आप कक्षा बी के माध्यम से इसका जिक्र कर रहे हों), कक्षा बी शुरू करने की कोई आवश्यकता नहीं है। B.f(); कॉलिंग A.f(); पर कॉल करने जैसा ही है।

अगर आप वर्ग बी का एक उदाहरण बना सकते हैं या वर्ग बी के एक स्थिर सदस्य/विधि का उपयोग

यहाँ केवल की स्थिति है कि वर्ग आरंभीकरण को गति प्रदान कर रहे हैं वर्ग बी के स्थिर प्रारंभ ब्लॉक निष्पादित किया जाएगा (JLS 12.4.1):

T is a class and an instance of T is created. 

T is a class and a static method declared by T is invoked. 

A static field declared by T is assigned. 

A static field declared by T is used and the field is not a constant variable (§4.12.4). 

T is a top level class (§7.6), and an assert statement (§14.10) lexically nested within T (§8.1.3) is executed. 
:

एक वर्ग या इंटरफ़ेस प्रकार टी निम्नलिखित में से किसी एक का पहली घटना से ठीक पहले प्रारंभ हो जाएगा

+0

अतिरिक्त का एक डुप्लिकेट: क्या कक्षा बी बी() को ओवरराइड करता है? – Niels

+0

@Niels, 'स्थिर 'विधियों पर ओवरराइड करने जैसी कोई चीज़ नहीं है। यदि 'बी' में' स्थिर 'विधि 'f()' है, तो इसे कॉल किया जाएगा। –

+0

@Niels आप एक स्थिर विधि को ओवरराइड नहीं कर सकते हैं। यदि बी अपनी स्थिर 'एफ()' विधि को परिभाषित करेगा, कक्षा बी लोड किया जाएगा और इसके स्थिर प्रारंभिक ब्लॉक को निष्पादित किया जाएगा, और 'f() 'विधि वह विधि है जिसे निष्पादित किया जाएगा।ऐसे मामले में, ए भी लोड किया जाएगा, क्योंकि यह बी – Eran

5

के बाद से ही वर्ग A विधि f() को परिभाषित करता है, वर्ग B भरी हुई लेकिन नहीं प्रारंभ है।

आप इसे देखने के लिए java -verbose:class MyClassName का उपयोग कर सकते हैं।

एक jdk6/jdk 8 मशीन पर, यह मुद्रित किया जाएगा।

[Loaded App from file:/C:/XXXX/] 
[Loaded A from file:/C:/XXXXXX] 
[Loaded B from file://C:/XXXXXXX] 
A static init 
f() called 

कक्षा B lazilyप्रारंभ किया जाएगा, लेकिन लालच से (क्योंकि यह संदर्भित किया जा रहा है) लोड।

अपना कोड A.f() पर बदलें। फिर आप देखेंगे कि B लोड नहीं हुआ है।

[Loaded App from file:/C:/XXXX/] 
[Loaded A from file:/C:/XXXXX] 
A static init 
f() called 

नोट: कक्षा लोड हो रहा है और प्रारंभ 2 अलग बातें हैं। विवरण के लिए Class.forName() के लिए प्रलेखन जांचें।

+0

का एक सुपर-क्लास है, क्या आपको पता है कि बी लोड होने की गारंटी है या क्या यह मंच निर्भर हो सकता है? –

+1

@pbabcdefp - यह वीएम (कार्यान्वयन) निर्भर होगा। कुछ कार्यान्वयन लालसा को 'बी' लोड करेंगे, अन्य लोग 'ए' को कॉल को सीधे हल कर सकते हैं, इस प्रकार' बी 'लोड नहीं कर सकते हैं। – TheLostMind

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