निम्नलिखित कोड संकलन में स्थिर ब्लॉक के अंदर static चर j के लिए विफल रहता है, जैसा कि टिप्पणी में बताया गया है।

हालांकि, यह m1() विधि के अंदर ठीक काम कर रहा है

class StaticBlock {
    static {
        m1();
        //compilation fails because variable are in read indirect state
        System.out.println(j);
    }

    static void m1() {
        System.out.println(j);
    }

    static int j = 10;

मुझे संकलन विफलता का मूल कारण पता है - परिवर्तनीय j अप्रत्यक्ष राज्य पढ़ें।

मेरा प्रश्न- यह व्यवहार क्यों है, हम 0 को स्थिर ब्लॉक के अंदर भी प्रिंट कर सकते हैं जैसा कि हम m1() में कर रहे हैं।

एपीआई डेवलपर्स ने इस विसंगति को क्या बनाया

0
Joker 20 अप्रैल 2019, 16:19

1 उत्तर

सबसे बढ़िया उत्तर

यह व्यवहार क्यों है, हम 0 स्थिर ब्लॉक के अंदर भी प्रिंट कर सकते हैं जैसे हम m1() में कर रहे हैं।

एपीआई डेवलपर्स ने इस विसंगति को क्या बनाया

क्लास इनिशियलाइज़ेशन के दौरान इवेंट्स के क्रम के लिए सरल विनिर्देशों के इर्द-गिर्द घूमने वाली प्रतिस्पर्धी प्राथमिकताएँ हैं, निरंतर (यानी final) क्लास फील्ड्स, प्रोग्रामर उम्मीदें, और कार्यान्वयन में आसानी।

स्थिर क्षेत्रों के मान एक अच्छा प्रारंभिक बिंदु प्रदान करते हैं। जावा ऐसे क्षेत्रों के डिफ़ॉल्ट मानों को देखने योग्य होने से बचाना चाहता है, और विशेष रूप से अन्य वर्ग चर के प्रारंभ में उपयोग किए जा रहे उनके डिफ़ॉल्ट मानों से बचने के लिए। इसलिए, इन्हें पहले स्टैटिक इनिशियलाइज़र ब्लॉक या अन्य क्लास वेरिएबल्स के इनिशियलाइज़र से पहले इनिशियलाइज़ किया जाता है। वे स्रोत कोड में दिखाई देने के क्रम में आरंभिक होते हैं, जो एक ऐसा नियम है जो मनुष्यों और संकलक दोनों के लिए समझना आसान है। लेकिन यह इस संभावना की पुष्टि करता है कि एक वर्ग चर का प्रारंभकर्ता दूसरे के डिफ़ॉल्ट मान को देखता है, आश्चर्यजनक, अवांछित परिणाम देता है। जावा इसलिए निर्दिष्ट करता है कि उस मामले का पता लगाया जाना चाहिए और संकलन समय पर खारिज कर दिया जाना चाहिए।

स्टेटिक इनिशियलाइज़र ब्लॉक और अन्य क्लास वेरिएबल्स के इनिशियलाइज़र को बाद में निष्पादित किया जाता है, जिस क्रम में वे सोर्स कोड में दिखाई देते हैं। आप जिस बाधा के बारे में पूछ रहे हैं वह मामला यहां उतना मजबूत नहीं है, लेकिन यहां वही नियम लागू करके स्थिरता चुनना उचित है जैसा कक्षा स्थिरांक पर लागू होता है। संयुक्त, प्रभाव को समझना आसान है और प्रारंभिक क्रम की भविष्यवाणी करना है जो कि क्लास वेरिएबल्स के प्रारंभिक मॉडल के अनुरूप है जो स्थिर प्रारंभकर्ता ब्लॉक का मूल्यांकन करने से पहले मूल्यांकन और असाइन किया जा रहा है।

लेकिन फिर स्थिर तरीके आते हैं। आरंभीकरण के दौरान उपयोग के लिए स्थैतिक तरीकों का उपलब्ध होना अत्यधिक वांछनीय है, लेकिन वे आरंभीकरण पूर्ण होने के बाद भी प्रयोग करने योग्य हैं, जब कोई भी आरंभीकरण-आदेश विचार प्रासंगिक नहीं हैं। इसलिए स्रोत कोड में उपस्थिति के क्रम के आधार पर स्थिर तरीकों की चर तक पहुंच को प्रतिबंधित करना संभव नहीं है। निश्चित रूप से, वीएम को इसके बजाय वर्ग चर के व्यक्तिगत प्रारंभिक स्थिति का ट्रैक रखने की आवश्यकता हो सकती है, या तो संकलन समय पर नियंत्रण-प्रवाह विश्लेषण या रनटाइम निगरानी के कुछ रूपों द्वारा, लेकिन ऐसी जटिलताओं की आवश्यकता के बजाय, जावा सादगी का विकल्प चुनता है, लोगों को अनुमति देता है जो ऐसा करने के लिए (वर्ग चर के डिफ़ॉल्ट मानों को देखकर) गड़बड़ी करने पर जोर देते हैं।

अंत में, मैं इस बात पर जोर देता हूं कि तथाकथित "रीड इनडायरेक्ट राइट ओनली स्टेट" तीसरे पक्ष के मॉडल का हिस्सा है कि यह सब कैसे काम करता है। जावा के पास ऐसी कोई अवधारणा नहीं है - जब यह स्थिर तरीकों के वर्ग चर के उपयोग की आवश्यकताओं की बात आती है, तो यह वही है जो सादगी के पक्ष में अस्वीकार करता है।

2
John Bollinger 20 अप्रैल 2019, 14:50