2011-11-16 9 views
19

निम्नलिखित कार्यक्रम का अपना कोई महत्व नहीं है। यह नीचे दिखाए गए अनुसार क्लास काउंटर के अंदर एक स्थिर क्षेत्र का उपयोग करके लूप के उपयोग के माध्यम से बनाए गए ऑब्जेक्ट्स की संख्या की गणना करता है।जावा में ऑब्जेक्ट बनाने का विवरण एकल-लाइन लूप का उपयोग करने की अनुमति नहीं देता है। क्यूं कर?

package temp; 

final class Counter 
{ 
    private static int cnt; 

    public Counter() 
    { 
     cnt++; 
    } 

    public static int show() 
    { 
     return(cnt); 
    } 
} 

final public class Main 
{ 
    public static void main(String[] args) 
    { 
     for (int i=0;i<50;i++) 
     { 
      Counter counter=new Counter(); 
     } 

     /*for (int i=0;i<50;i++) 
      Counter counter=new Counter();*/ 

     System.out.print("\nNumber of objects constructed:->"+Counter.show()+"\n\n"); 
    } 
} 

केवल सवाल है कि यहाँ पाश के लिए टिप्पणी की पाश के लिए ऊपर के रूप में ही इसका मतलब है (एक ही बात भी थोड़ी देर के पाश करने के लिए लागू किया जाता है) सब पर एक compile- के कारण काम नहीं करता है समय त्रुटि जो इंगित करती है कि "कोई कथन" का अर्थ यह नहीं है कि इस विशेष स्थिति में, ब्रेसिज़ की जोड़ी अनिवार्य है, भले ही लूप में केवल एक कथन शामिल हो! क्यूं कर?

उत्तर

27

को समझने के लिए कि ऐसा क्यों होता है, तो आप भाषा विनिर्देश में Java's Blocks and Statements syntax को देखने के लिए की है।

ForStatement: 
    for (ForInitopt ; Expressionopt ; ForUpdateopt) 
     Statement 

वक्तव्य के रूप में परिभाषित किया गया है: के रूप में

एक ForStatement परिभाषित किया गया है

Statement: 
    StatementWithoutTrailingSubstatement 
    LabeledStatement 
    IfThenStatement 
    IfThenElseStatement 
    WhileStatement 
    ForStatement 

StatementWithoutTrailingSubstatement: 
    Block 
    EmptyStatement 
    ExpressionStatement 
    SwitchStatement 
    DoStatement 
    BreakStatement 
    ContinueStatement 
    ReturnStatement 
    SynchronizedStatement 
    ThrowStatement 
    TryStatement 

फिर, ब्लॉक को देख:

Block: 
    { BlockStatementsopt } 

BlockStatements: 
    BlockStatement 
    BlockStatements BlockStatement 

BlockStatement: 
    LocalVariableDeclarationStatement 
    ClassDeclaration 
    Statement 

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

+1

+1। –

+2

जसकाव सही है। एक घोषणा कथन एक मानक अनिवार्य बयान के समान नहीं है, और एक लूप बॉडी के रूप में अकेले खड़े नहीं हो सकता है (और संभवत: यदि/अन्य के शरीर के रूप में नहीं)। ब्रेसिज़ को खराब विचार होने से रोकने के लिए –

6

क्योंकि आप एक स्कोप चर बना रहे हैं। जावा आपको बता रहा है कि यह कुछ भी नहीं करता है क्योंकि यह सब कुछ स्मृति आवंटित करता है और जैसे ही लूप फिर से गुजरता है, आप उसे खो देते हैं और एक नया बनाते हैं। अनिवार्य रूप से संपूर्ण पाश एक एनओपी है, यही कारण है कि यह आपको बता रहा है कि यह कुछ भी बयान नहीं देता है।

लूप द्वारा एनओपी होने का मतलब है कि लूप में घोषणा एक एनओपी है।

ब्रेसिज़ काम के साथ संस्करण का कारण यह है कि संकलक दायरे के भीतर उपयोग का निरीक्षण नहीं करता है क्योंकि ब्रेसिज़ हैं। एक लूप स्कोप होने पर बनाए गए पार्स पेड़ बनाम एक पंक्ति कथन से उत्पन्न पार्स पेड़ के साथ शायद कुछ ऐसा करना संभव है।

+2

+1 अधिक स्पष्ट होने के लिए, ऐसा इसलिए है क्योंकि संकलक * जानता है * आप दूसरे मामले में कुछ भी नहीं कर रहे हैं और आपको बताते हैं। पहले में यह नहीं है। –

+2

यह सच नहीं है। कन्स्ट्रक्टर एक स्थिर काउंटर को बढ़ाता है, इसलिए 'नए काउंटर()' के दुष्प्रभाव होते हैं और यह एक ओपी-ओपी –

+0

@BrianRoach नहीं है इसे साफ़ करने के लिए धन्यवाद।मैंने कभी ओओपी भाषा के लिए एक कंपाइलर नहीं लिखा है, लेकिन मुझे लगता है कि एक लाइन स्टेटमेंट को अधिक जटिल स्कोपिंग की आवश्यकता नहीं होती है, जबकि कई कथनों के साथ लूप को अलग-अलग प्रतीक रिज़ॉल्यूशन की आवश्यकता होती है। –

4

@JasCav सही है, लेकिन आप इसे संकलित करने के लिए प्राप्त कर सकते हैं:

for (int i=0;i<50;i++) 
    new Counter(); 
+0

हाँ, यह काम करता है क्योंकि यह घोषणा नहीं है। जेएलएस से इसे खोदने के लिए –

4

आप भी इसे ब्रेसिज़ के बिना इस तरह से काम करने के लिए प्राप्त कर सकते हैं:

Counter counter; 
    for (int i = 0; i < 50; i++) 
    counter = new Counter(); 

नहीं तो ऐसा कोई कारण क्या तुमने कभी ऐसा करना चाहते हैं कि। ब्रैकेट को छोड़ना वास्तव में खराब विचार है क्योंकि एक कथन जोड़ने से वास्तव में नियंत्रण प्रवाह में परिवर्तन होता है।

+0

+1। बयान के लिए वही। केवल तभी करें जब आप "बॉडी" को उसी पंक्ति पर रखने के लिए जा रहे हैं जैसे कि आपने जो किया है उसके लिए सिग्नल के प्रकार के रूप में। –

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

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