2012-06-22 85 views
21
public class Foo { 
    public static void main(String[] args) { 
     float f; 
     System.out.println(f); 
    } 
} 

प्रिंट बयान निम्नलिखित संकलन-टाइम त्रुटि,जावा: मुझे एक आदिम स्थानीय चर प्रारंभ करने की आवश्यकता क्यों है?

स्थानीय चर च

प्रारंभ नहीं किया गया है जावा में पुरातन पहले से ही एक default value (float = 0.0f) है, तो मैं क्यों आवश्यक कर रहा हूँ का कारण बनता है एक परिभाषित करने के लिए?


संपादित करें:

तो, यह काम करता है

public class Foo { 
    float f; 
    public static void main(String[] args) { 
     System.out.println(new Foo().f); 
    } 
} 

धन्यवाद, हर कोई!

+6

संपादित करें पुन: हां, यह काम करता है, लेकिन प्रारंभ से बचने के लिए एक क्षेत्र के लिए एक स्थानीय को बढ़ावा देने के लिए एक उचित उदाहरण :-) – fvu

+1

@fvu, यह एक उदाहरण है, तो यह कुछ उद्देश्य में कार्य करता नहीं हो सकता है। : डी – user1329572

उत्तर

41

क्योंकि यह एक स्थानीय चर है। यही कारण है कि इसे कुछ भी सौंपा गया नहीं है:

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

संपादित करें: जावा इस संकलन त्रुटि को क्यों उठाता है? अगर हम IdentifierExpression.java वर्ग फ़ाइल को देखें, हम इस ब्लॉक मिलेगा:

... 
if (field.isLocal()) { 
      LocalMember local = (LocalMember)field; 
      if (local.scopeNumber < ctx.frameNumber && !local.isFinal()) { 
       env.error(where, "invalid.uplevel", id); 
      } 
      if (!vset.testVar(local.number)) { 
       env.error(where, "var.not.initialized", id); 
       vset.addVar(local.number); 
      } 
      local.readcount++; 
     } 
... 

के रूप में कहा गया है (if (!vset.testVar(local.number)) {), JDK चेक (testVar के साथ) यदि चर असाइन किया गया है (Vset's source code जहाँ हम testVar कोड प्राप्त कर सकते हैं)। यदि नहीं, तो यह एक properties file से त्रुटि var.not.initialized को जन्म देती है:

... 
javac.err.var.not.initialized=\ 
    Variable {0} may not have been initialized. 
... 

Source

+5

ओह वाह, आज पूरी तरह से कुछ नया सीखा! : डी – user1329572

+1

यह वास्तव में * व्याख्या क्यों नहीं करता है "क्यों", है ना? – kryger

+1

@ क्रिएगर कृपया संपादन देखें। – Zakaria

5

क्लास फ़ील्ड्स (गैर -final वैसे भी) डिफ़ॉल्ट मानों में प्रारंभ किए गए हैं। स्थानीय चर नहीं हैं।

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

तो

class C { 
    float f; 
} 

में f की तरह एक (गैर final) क्षेत्र

void myMethod() { 
    float f; 
} 

में 0f लेकिन स्थानीय चर f के लिए शुरू हो जाएगा नहीं होगा।

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

+1

+1, गैर-'फाइनल' बिट के बारे में अच्छी जानकारी! : डी – user1329572

13

वास्तव में, संकलक , अपने float f करने के लिए डिफ़ॉल्ट मान निर्दिष्ट नहीं है क्योंकि इस मामले में यह एक स्थानीय चर रहा है - और नहीं एक क्षेत्र:

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

2

वास्तव में स्थानीय चर stack.Hence में जमा हो जाती है वहाँ स्थानीय variable.It के लिए किसी भी पुराने मूल्य वर्तमान लेने का एक मौका है सुरक्षा कारणों के लिए एक बड़ी चुनौती है .. हां जावा कहते हैं कि आपको उपयोग से पहले स्थानीय वैरिएबल शुरू करना है।

1

हाय लोग समाधान सरल है। ढेर मेमोरी पर संग्रहीत मानों को संकलक आधारित डाटाटाइप द्वारा प्रारंभ किया जाता है लेकिन स्थानीय चर स्टैक मेमोरी पर संग्रहीत होते हैं, इसलिए हमें इसे स्पष्ट रूप से इनकार करना होगा।