मैं जावा का अध्ययन कर रहा हूं, मुझे जावा वैरिएबल स्कोप पता है, जैसे कि क्लास लेवल, मेथड लेवल, ब्लॉक लेवल। हालांकि, जब मैं परिवर्तनीय दायरे का अभ्यास करने का प्रयास करता हूं, तो मैं अपने कोड में त्रुटि को पूरा करता हूं। मेरा कोड निम्नलिखित है:

public class HelloWorld {
    public static void main(String[] args) {
        int c;
        for (int i=0; i <5; i++) {
            System.out.println(i);
            c = 100;
        }
        System.out.println(c);
    }
}

जब मैं इस कोड को चलाता हूं, तो यह त्रुटि प्रदर्शित करता है: the c variable might not have been initialized, लेकिन जब मैं अपना कोड निम्नलिखित में बदलता हूं:

public class HelloWorld {
    public static void main(String[] args) {
        int c=0;
        for (int i=0; i <5; i++) {
            System.out.println(i);
            c = 100;
        }
        System.out.println(c);
    }
}

कोड 100 प्रिंट होगा।

मुझे अपने कोड में दायरे को कैसे समझना चाहिए?

0
tdycss 23 पद 2020, 12:05

3 जवाब

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

जावा में स्थानीय चरों को डिफ़ॉल्ट मान के साथ प्रारंभ नहीं किया जाता है (इसके विपरीत, उदाहरण के लिए कक्षाओं का क्षेत्र)। भाषा विनिर्देश से एक ( §4.12.5) निम्नलिखित पढ़ सकते हैं:

एक स्थानीय चर (§14.4, §14.14) को स्पष्ट रूप से एक मान दिया जाना चाहिए उपयोग करने से पहले, या तो इनिशियलाइज़ेशन (§14.4) या असाइनमेंट . द्वारा (§१५.२६), एक तरह से जिसे निश्चित नियमों का उपयोग करके सत्यापित किया जा सकता है असाइनमेंट (§16 (निश्चित असाइनमेंट))।

चूंकि यह स्पष्ट रूप से जावा भाषा विनिर्देश पर सेट है, इसलिए संकलक यह अनुमान लगाने की कोशिश नहीं करेगा (और नहीं करना चाहिए) कि चर c हमेशा लूप के अंदर अपडेट किया जाएगा:

public class HelloWorld {
    public static void main(String[] args) {
        int c;
        for (int i=0; i <5; i++) {
            System.out.println(i);
            c = 100;
        }
        System.out.println(c);
    }
}

कंपाइलर मानक को सख्ती से लागू करता है और आपको त्रुटि के साथ इसके नियमों में से एक को तोड़ने के बारे में सूचित करता है:

"variable c might not have been initialized"

इसलिए भले ही आपका कोड औपचारिक रूप से मान्य साबित हो सकता है, यह आपके आवेदन के तर्क का विश्लेषण करने का प्रयास करने के लिए संकलक नौकरी नहीं है, और न ही के नियम स्थानीय चर आरंभीकरण उस पर भरोसा करते हैं। संकलक जाँचता है कि क्या चर c को स्थानीय चर आरंभीकरण नियमों के अनुसार प्रारंभ किया गया है, और प्रतिक्रिया तदनुसार (जैसे, प्रदर्शित करता है int c; के मामले में संकलन त्रुटि)।

1
dreamcrash 23 पद 2020, 13:11

यह गुंजाइश का मुद्दा नहीं है। आपका वेरिएबल c मेथड-स्कोप्ड है और पूरे main मेथड में उपलब्ध है। यह एक कंपाइलर फीचर है। संकलन समय पर यह जांच नहीं कर सकता है कि "के लिए" चक्र चर को प्रारंभ करने के लिए कम से कम एक बार चलाएगा। इसलिए यह कहता है कि जब आप इसे प्रिंट करने का प्रयास कर रहे होते हैं तो वेरिएबल को इनिशियलाइज़ नहीं किया जा सकता है। तो c प्रिंट विधि के लिए उपलब्ध है, लेकिन संकलक सुनिश्चित नहीं है कि इसे प्रारंभ किया गया था।

0
Vitaly Kolesnikov 23 पद 2020, 12:17

क्योंकि आप यह सुनिश्चित नहीं कर सकते कि चर c हमेशा लूप में आरंभीकृत हो। उदाहरण के लिए यदि आपका कोड इस तरह दिखता है:

public class HelloWorld {
    public static void main(String[] args) {
        int c;
        for (int i=0; i <0; i++) {
            System.out.println(i);
            c = 100;
        }
        System.out.println(c);
    }
}

आपका कोड कभी भी लूप तक नहीं पहुंचेगा, फिर वेरिएबल c को कभी भी इनिशियलाइज़ नहीं किया जाएगा। यही कारण है कि जावा भाषा अनुरोध करती है कि यदि आप इसे लूप के बाहर उपयोग करते हैं तो आप लूप के बाहर एक चर प्रारंभ करते हैं।

0
Thuat Nguyen 23 पद 2020, 12:18