2012-11-25 22 views
7

संभव डुप्लिकेट:
Java static class initialization
in what order are static blocks and static variables in a class executed?आदेश, जावा

मुझे इस कोड की जवाब 1 है चलाने के लिए, मैंने सोचा कि यह होगा 2. क्या प्रत्येक चरण में प्रारंभिकरण और के मूल्य का क्रम है?

public class Test { 

static {k = 2;} 
static int k = 1; 

public static void main(String[] args) { 
    System.out.println(k); 
} 
} 

संपादित करें 1: "के डिफ़ॉल्ट मान पर सेट है" के अनुवर्ती के रूप में, तो यह अगला कोड संकलित क्यों नहीं होता है? एक त्रुटि है "परिभाषित होने से पहले किसी फ़ील्ड को संदर्भित नहीं कर सकता"।

public class Test { 

static {System.out.println(k);} 
static int k=1; 

public static void main(String[] args) { 
    System.out.println(k); 
} 
} 

संपादित करें 2: कुछ लोगों के लिए मुझे यह कारण नहीं है कि^"के" के बजाय "test.k" के बजाय काम करता है।

सभी उत्तरों के लिए धन्यवाद। यह सूख जाएगा: डी

+1

सबसे पहले, के को डिफ़ॉल्ट मान असाइन किया जाएगा, फिर शीर्ष से, स्थिर कोड चलाया जाएगा और 2 असाइन किया जाएगा, फिर 1 असाइन किया जाएगा। फिर मुख्य समारोह को बुलाया जाता है और प्रिंट आउट करता है। 'स्थिर int k = 1' प्रभावी रूप से' स्थिर int k; 'घोषणा है, फिर' स्थिर {k = 1; } ' – nhahtdh

+0

@ केनीटीएम हाँ, अगर मैंने इसे उस पोस्ट में चलाया था जिस तरह से आप पेस्ट करते हैं, तो मुझे पता चलेगा कि क्या हो रहा है। – Hoto

+0

@nhahtdh k को डिफ़ॉल्ट मान असाइन किया जाएगा? तो फिर क्यों इस कोड comiple नहीं करता है: सार्वजनिक वर्ग टेस्ट { \t \t स्थिर {println (ट); k = 2;} \t स्थिर पूर्णांक k; \t \t public static void (String [] args) { \t \t println (ट); \t} } – Hoto

उत्तर

7

वे आपको लिखने के क्रम में निष्पादित किए जाते हैं। यदि कोड है:

public class Test { 

    static int k = 1; 
    static {k = 2;} 

    public static void main(String[] args) { 
     System.out.println(k); 
    } 

} 

तो उत्पादन 2.

आरंभीकरण के आदेश है हो जाता है: ..the class variable initializers and static initializers of the class..., in textual order, as though they were a single block.

और मूल्यों (अपने कोड के लिए) इस प्रकार हैं: k = 0 (डिफ़ॉल्ट), तो यह 2 पर सेट है, तो यह करने के लिए 1.

वापस सेट है आप देख सकते हैं निम्नलिखित कोड चलाकर कि यह वास्तव में 2 पर सेट है:

private static class Test { 

    static { 
     System.out.println(Test.k); 
     k = 2; 
     System.out.println(Test.k); 
     } 
    static int k = 1; 

    public static void main(String[] args) { 
     System.out.println(k); 
    } 
} 
+0

मेरे प्रश्न में मेरा मतलब क्या नहीं था। मैं प्रत्येक चरण में के प्रारंभिकरण और के मूल्यों का आदेश चाहता था। – Hoto

+0

ठीक है, मैंने एक और विस्तृत स्पष्टीकरण जोड़ा। – tibtof

+0

हाँ ... लेकिन अब आपके उत्तर में एक अराजकता है xD – Hoto

3

लघु जवाब

जब वर्ग के प्रारंभ में शुरू होता है, k 0.

स्थिर ब्लॉक (क्योंकि यह घोषणा में काम के पहले आता है) का प्रारंभिक मूल्य होगा तो मार डाला जाता है, और k आवंटित किया जाएगा 2.

फिर घोषणा में प्रारंभकर्ता निष्पादित किया गया है, और k 1 असाइन किया जाएगा।

लांग स्पष्टीकरण

, हमें this example का उपयोग करते हैं के बाद से अपने उदाहरण थोड़ा सरल है:

class TestInitOrder { 
    static { 
    System.out.println(TestInitOrder.stat1); 
    System.out.println(TestInitOrder.stat2); 
    System.out.println(TestInitOrder.str); 
    System.out.println(TestInitOrder.str2); 

    str = "something"; 

    System.out.println(TestInitOrder.str); 
    System.out.println(TestInitOrder.str2); 
    System.out.println(TestInitOrder.lazy); 
    System.out.println(TestInitOrder.second); 
    } 

    private static final int stat1 = 10; 
    static final String str2 = "sdfff"; 
    static String str = "crap"; 
    private static int stat2 = 19; 
    static final Second second = new Second(); 
    static final int lazy; 

    static { 
    lazy = 20; 
    } 

    static { 
    System.out.println(TestInitOrder.str2); 
    System.out.println(TestInitOrder.stat2); 
    System.out.println(TestInitOrder.str); 
    System.out.println(TestInitOrder.lazy); 
    System.out.println(TestInitOrder.second); 
    } 

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

} 

class Second { 
    public Second() { 
    System.out.println(TestInitOrder.second); 
    } 
} 
Java Language Specification के अनुसार

, section 4.12.5 से:

एक कार्यक्रम में हर चर इसके मूल्य का उपयोग करने से पहले एक मूल्य होना चाहिए:

  • प्रत्येक वर्ग चर, उदाहरण चर, या सरणी घटक एक डिफ़ॉल्ट मान के साथ आरंभ नहीं हो जाता है, जब यह सभी प्रकार के लिए डिफ़ॉल्ट मान निर्दिष्ट

(विनिर्देश से निम्नलिखित लाइनों बनाई गई है, मूल रूप से आदि 0 के कुछ फार्म, जैसे 0, 0.0d, null, false,)

तो इससे पहले कि वर्ग आरंभ नहीं हो जाता (कारण these reasons में से एक) के लिए, चर एक प्रारंभिक मूल्य का आयोजन करेगा।

detailed initialization procedure के अनुसार (केवल दिलचस्प चरणों यहाँ उद्धृत कर रहे हैं, और जोर मेरा):

6. [...] फिर, final वर्ग चर और इंटरफेस की क्षेत्रों प्रारंभ जिनके मान संकलन समयनिरंतर भाव हैं (§8.3.2.1, §9.3.1, §13.4.9, §15.28)।

[...]

9. इसके बाद, वे या तो वर्ग चर initializers और वर्ग के स्थिर initializers, या इंटरफेस के क्षेत्र initializers निष्पादित शाब्दिक क्रम में जैसे कि वे एक विशाल खंड में थे ।

हमें 4 final वर्ग चर के साथ, चरण 6 पर नजर डालते हैं: stat1, str2, second, lazy

10 के बाद से निरंतर अभिव्यक्ति है, और इसलिए "sdfff" है, और निष्पादन के आदेश के कारण, यह को प्रारंभिक मूल्य का निरीक्षण str2 और stat1 के लिए संभव नहीं है। अवलोकन करने के लिए, सबसे पहले आप चरण 9 में कर सकते हैं।

second का मामला दर्शाता है कि जब दाएं हाथ की ओर संकलन-समय निरंतर अभिव्यक्ति नहीं होती है, तो इसका प्रारंभिक मान दिखाई देता है।

lazy का मामला अलग है, क्योंकि स्थिर ब्लॉक में असाइनमेंट किया जाता है, और इसलिए चरण 9 में होता है - इसलिए इसका प्रारंभिक मूल्य देखना संभव है। (ठीक है, संकलक सावधानीपूर्वक जांच करता है कि lazy बिल्कुल एक बार असाइन किया गया है)।


संकलन समय निरंतर अभिव्यक्ति के साथ अंतिम वर्ग चर के प्रारंभ होने के बाद स्थिर ब्लॉक के निष्पादन और initializers के बाकी आता है। str चर के उपयोग के साथ प्रदर्शन किया - -

आप उदाहरण से देख सकते हैं, स्थिर ब्लॉक और आरंभीकरण शाब्दिक क्रम के अनुसार होता है यह पहली बार null, तो something, तो crap के रूप में बाहर छपा है।

+0

@EJP है: ध्यान दें कि 2 स्थितियां 1) ** अंतिम ** कक्षा चर और 2) प्रारंभकर्ता संकलन-समय निरंतर है जो किया जाता है चरण 6. यहां कोई विरोधाभास नहीं है। आप विचारधारा पर कार्यक्रम भी देख सकते हैं। – nhahtdh

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