लघु जवाब
जब वर्ग के प्रारंभ में शुरू होता है, 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
के रूप में बाहर छपा है।
सबसे पहले, के को डिफ़ॉल्ट मान असाइन किया जाएगा, फिर शीर्ष से, स्थिर कोड चलाया जाएगा और 2 असाइन किया जाएगा, फिर 1 असाइन किया जाएगा। फिर मुख्य समारोह को बुलाया जाता है और प्रिंट आउट करता है। 'स्थिर int k = 1' प्रभावी रूप से' स्थिर int k; 'घोषणा है, फिर' स्थिर {k = 1; } ' – nhahtdh
@ केनीटीएम हाँ, अगर मैंने इसे उस पोस्ट में चलाया था जिस तरह से आप पेस्ट करते हैं, तो मुझे पता चलेगा कि क्या हो रहा है। – Hoto
@nhahtdh k को डिफ़ॉल्ट मान असाइन किया जाएगा? तो फिर क्यों इस कोड comiple नहीं करता है: सार्वजनिक वर्ग टेस्ट { \t \t स्थिर {println (ट); k = 2;} \t स्थिर पूर्णांक k; \t \t public static void (String [] args) { \t \t println (ट); \t} } – Hoto