2013-02-24 16 views
5

जावा में स्विच स्टेटमेंट में केस के रूप में अंतिम वैरिएबल क्यों हो सकता है? ##जावा में स्विच स्टेटमेंट में केस के रूप में अंतिम वैरिएबल क्यों हो सकता है?

जेडीके 7 में मेरे द्वारा चेक किए गए मूल्य को अंतिम चर के रूप में पुन: असाइन नहीं किया जा सकता है, जैसा कि नीचे दिखाया गया है। लेकिन, आखिरी चर "x" को अंतिम स्टेटस "एक्स" के लिए केस इवेंटहो मूल्य के लिए स्विच स्टेटमेंट में क्यों शामिल किया जा सकता है?

यह क्यों किया जा सकता है घटनाक्रम ओरेकल परिभाषित करता है कि जावा कंपाइलर अंतिम वैरिएबल लेता है क्योंकि मान प्रारंभ होता है लेकिन परिवर्तनीय नाम नहीं है? http://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.12.4

कृपया मुझे बताएं कि क्या यह जावा कंपाइलर की तकनीकी त्रुटि है या स्विच स्टेटमेंट में अंतिम चर के मामले की जांच करने के अपवाद या विशेष उपयोग हैं?

class Example{ 
    public static void main(String args[]){ 
     final int x=100; 
     //x=200; //error: cannot assign a value to final variable x 

     //The below piece of code compiles 
     switch(x){ 
      case 200: System.out.println("200"); 
      case 300: System.out.println("300"); 
     } 

    } 
} 
+4

क्या आपको पता है कि स्विच क्या करता है? आप [ट्यूटोरियल] (http://docs.oracle.com/javase/tutorial/java/nutsandbolts/switch.html) पढ़ना चाहेंगे। –

+0

क्यों संकलन-समय स्थिरांक पर स्विच करने में सक्षम नहीं हैं? –

+3

'स्विच' किसी भी मूल्य को पुन: असाइन नहीं कर रहा है। –

उत्तर

2

ठीक है, आप एक समारोह में एक final पैरामीटर पारित कर सकते हैं:

//the function doesn't know what x value is, 
//but it knows that it can't modify its value 
public someFunction(final int x) { 

    x += 1; //compiler error 
    switch(x) { 
     case 200: System.out.println("200"); 
      break; 
     case 300: System.out.println("300"); 
      break; 
    } 
} 

//the function doesn't know what x value is, 
//but it knows that it can modify it 
//for internal usage 
public someOtherFunction(int x) { 

    switch(x) { 
     case 200: 
      x += 200; 
      break; 
     case 300: 
      x += 300; 
      break; 
    } 
    System.out.println(x); 
} 
+5

क्या आपने पढ़ा उदाहरण? –

+1

मुझे लगता है कि आप वही जवाब दे रहे हैं जो ओपी पूछ रहा है :) –

+0

gekkostate की टिप्पणी इस प्रश्न के लिए सबसे अच्छा जवाब है। –

4

क्या इस स्थिति के बारे में?

public class Foo 
{ 
    private final int x; 

    public Foo(int x){this.x = x;} 

    public void boo() 
    { 
     switch(x) 
     { 
      case 200: System.out.println("200"); 
      case 300: System.out.println("300"); 
     } 
    } 
} 

या हो सकता है यह एक:

public static void doSomething(final int x) 
{ 
    switch(x) 
    { 
     case 200: System.out.println("200"); 
     case 300: System.out.println("300"); 
    } 
} 
+1

मैंने सटीक वही उत्तर पोस्ट करने के बारे में सोचा था, लेकिन आपने इसे जल्दी किया ... +1 – codeMan

1

आप final संशोधक एक फर्क करने के लिए क्यों उम्मीद करेंगे? उस मूल्य पर असाइन करने की आवश्यकता नहीं है जिसे चालू किया जा रहा है।

क्या आप वाकई समझते हैं कि switch कथन क्या करता है?

+0

हाँ मुझे यकीन है कि समस्या यह है कि यह संकलन भी अंतिम चर है, –

3
switch(x){ 
    case 200: System.out.println("200"); break; 
    case 300: System.out.println("300"); 
} 

अनिवार्य रूप से

if (x == 200) 
    System.out.println("200"); 
else if (x == 300) 
    System.out.println("300"); 

यह सिर्फ, की तुलना है बताए नहीं है, तो तथ्य यह है कि x बदला नहीं जा सकता कोई फर्क नहीं पड़ता है।

तकनीकी तौर पर आप उदाहरण होगा थोड़ा अलग (यदि आप एक break की जरूरत नहीं है क्योंकि):

if (x == 200) 
    System.out.println("200"); 
if (x == 200 || x == 300) 
    System.out.println("300"); 

या ऐसा ही कुछ।

तथ्य यह है कि x कभी भी 200 या 300 कोड संकलित नहीं कर सकता है। हालांकि यह जावा को स्विच कथन को अनुकूलित करने की अनुमति दे सकता है।

+0

+1 जोड़ने के लिए "तथ्य वह एक्स 200 या 300 कभी नहीं हो सकता है, कोड को संकलित नहीं करता है। हालांकि यह जावा को स्विच कथन को अनुकूलित करने की अनुमति दे सकता है। " मुझे लगता है कि यह ओपी के सवाल का पर्याप्त जवाब देता है। –

0

मुझे लगता है कि switch के बारे में चेतावनी या चेतावनी देने के लिए अनुकूलन है- संकलन समय पर ज्ञात आंकड़े हमेशा एक ही मामले में मूल्यांकन किए जाने के लिए संकलक में लागू नहीं किया जाता है, क्योंकि यह एक दुर्लभ मामला है।

निम्न कोड चेतावनियों या त्रुटियों के बिना भी संकलित करता है।

switch(3){ 
    case 2: 
     System.out.println("two"); 
     break; 
    case 3: 
     System.out.println("three"); 
     break; 
    } 

case 2: भाग में पहुंच योग्य नहीं कोड के बारे में संकलक द्वारा एक चेतावनी अच्छा होगा, लेकिन लागू नहीं है।

+0

मेरे कोड में इस मामले के विपरीत, अंतिम चर घोषित किया गया है और स्विच स्टेटमेंट में पैरामीटर के रूप में उपयोग किया जाता है, इसलिए संकलक जानता है कि किसी भी ऑटर वैल्यू को वैरिएबल एक्स को असाइन नहीं किया जा सकता है, इसे एक कॉन्सटेंट 100 के रूप में लेता है, मैं पूछ रहा हूं ' क्यों एक केस स्टेटमेंट संकलित कर सकता है संकलक भी जानता है कि अंतिम चर में कोई मामला नहीं हो सकता है, –

+0

@ डीजे तिशन: संकलक को आपके कोड को संकलित क्यों नहीं करना चाहिए, भले ही आपके स्विच ब्लॉक में कोई भी कोड निष्पादित न हो । इसका वाक्यविन्यास सही है और इसलिए यह वैध कोड है। आपका अंतिम चर मेरे निरंतर मूल्य की तरह है, आपका और मेरा, पहुंचने योग्य कोड तक पहुंचता है, दोनों मामलों में संकलक इसके बारे में चेतावनी नहीं देता है। – MrSmith42

0

अधिकांश संकलक ऑप्टिमाइज़ेशन एल्गोरिदम का उपयोग करके कोड अनुकूलित करते हैं जो हेरिस्टिक (अनुभव-आधारित तकनीकों) और अनुमानों पर भरोसा करते हैं। नीचे कोड नियंत्रण प्रवाह विश्लेषण में आ जाएगा। मैंने कार्यक्रम के बहुत सारे नमूने

केस ए) यदि अंतिम चर के साथ - कंपाइलर एक चेतावनी मृत कोड फेंकता है। जेनरेट बाइट कोड में कोई अन्य-कथन नहीं है।

public static void main(java.lang.String[]) 

Stack=1, Locals=2, Args_size=1 
0: iconst_0 
1: istore_1 
2: return 
LineNumberTable: 
line 42: 0 
line 54: 2 

LocalVariableTable: 
Start Length Slot Name Signature 
0  3  0 args  [Ljava/lang/String; 
2  1  1 selection  I 


} 

केस बी) यदि अंतिम चर के बिना - कोई संकलक त्रुटि नहीं है लेकिन कोई कोड अनुकूलन भी नहीं है।

 final int selection i=100; //case A 
     //int selection i=100; //case B 

    if(selection==1){ 
     System.out.println("Hi"); 
    }else if(selection==2){ 

    }else{ 

    } 

प्रकरण सी) अगर-किसी और अंतिम चर के साथ लेकिन अगर-बाकी बयान किसी अन्य विधि में डाल दिया जाता

 computeIfLese(int selection) 
  • कोई कोड अनुकूलन किया के बाद से इस विधि के साथ अन्य उदाहरण द्वारा लागू किया जा सकता है कहते हैं पैरामीटर के अलग-अलग मूल्य (जाहिर है)।

चूंकि संकलक अनुकूलन तकनीक हेरिस्टिक्स पर आधारित है, इसलिए यह मामला मिस के रूप में होता, लेकिन सबसे दुर्लभ मामले के बारे में कौन सोचता। जावा देवताओं से

टिप्पणियां की प्रतीक्षा ... :)

यहाँ एक रहने वाले सबूत है कि संकलक अनुकूलित this.Check लेबल 5 नहीं किया है: अंतिम पैरामीटर होने के अलावा

public static void main(java.lang.String[]); 
Code: 
Stack=2, Locals=2, Args_size=1 
0: bipush 100 
2: istore_1 
3: bipush 100 
5: lookupswitch{ //2 
    200: 32; 
    300: 40; 
    default: 48 } 
32: getstatic #16; //Field java/lang/System.out:Ljava/io/PrintStream; 
35: ldC#22; //String 200 
37: invokevirtual #24; //Method java/io/PrintStream.println:(Ljava/lang/String;)V 
40: getstatic #16; //Field java/lang/System.out:Ljava/io/PrintStream; 
43: ldC#30; //String 300 
45: invokevirtual #24; //Method java/io/PrintStream.println:(Ljava/lang/String;)V 
48: return 
    LineNumberTable: 
line 11: 0 
line 15: 3 
line 17: 32 
line 18: 40 
line 21: 48 

LocalVariableTable: 
Start Length Slot Name Signature 
0  49  0 args  [Ljava/lang/String; 
3  46  1 selection  I 

StackMapTable: number_of_entries = 3 
frame_type = 252 /* append */ 
offset_delta = 32 
locals = [ int ] 
    frame_type = 7 /* same */ 
frame_type = 7 /* same */ 


} 
0

, एक अंतिम स्थानीय चर उन मानों को पकड़ सकते हैं जो संकलन-समय पर ज्ञात नहीं हैं:

public static void main(String args[]){ 
    final int x; 

    if (someMethod()) 
     x = 200; 
    else 
     x = 300; 

    switch(x){ 
     case 200: System.out.println("200"); 
     case 300: System.out.println("300"); 
    } 

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