2013-06-07 14 views
10

क्यों जावा में स्विच केस स्टेटमेंट केवल पूर्णांक, लघु, बाइट और वर्ण लेता है और अन्य डेटा प्रकार नहीं? लाभ क्या हो सकता है? विस्तार से समझाओ।जावा में स्विचकेस कथन इस तरह क्यों काम करता है?

+6

यह भी JDK 1.7 के बाद से तार और Enums स्वीकार करता है। –

+2

यह एक भाषा आवश्यकता है। जावा 7 के तहत, अब यह 'स्ट्रिंग' का समर्थन करता है और चूंकि' enum' पेश किया गया था, यह 'enum' का भी समर्थन करता है। सवाल वास्तव में नीचे आता है कि आप एक मनमानी वस्तु के लिए एक मामला कैसे परिभाषित करेंगे? – MadProgrammer

+0

@MadProgrammer अच्छी तरह से आप एक मनमानी वस्तु बना सकते हैं और मुझे लगता है कि प्रत्येक मामले के खिलाफ मिलान करने के लिए बराबर का उपयोग कर सकते हैं। – Thihara

उत्तर

16

आमतौर पर भाषा डिजाइन प्रश्न उबालते हैं "क्योंकि डिजाइनरों ने ऐसा करने का फैसला किया है।" यह उन समयों में से एक और है।

लेकिन जावा में कुछ उत्पत्ति सी है, जिसने वही काम किया है, और 80 के दशक में यह निर्णय मुझे समझाया गया था क्योंकि तब संकलक स्विच को एक जंप टेबल में बदल सकता था: असल में, कोड के पते का प्रत्येक ब्लॉक एक टेबल में रखा गया है और switch पता प्राप्त करने के लिए आपके द्वारा पास किए गए मान का उपयोग करके तालिका लुकअप (आमतौर पर सरणी में सूचीबद्ध या सरणी की कम से कम लिंक की सूची) के बाद एक श्रेणी की जांच बन जाती है, और उसके बाद उस पते पर जाएं। केवल परिदृश्य उस परिदृश्य में समझ में आता है। याद रखें कि कंप्यूटर हमेशा जितना तेज़ नहीं थे। सी 60 के उत्तरार्ध में काम के आधार पर शुरुआती 70 के दशक में डिजाइन किया गया था, जब कंप्यूटर बहुत धीमे थे।

ही वाक्यात्मक जावा और सी, JavaScript जैसी रूप में परंपरा में कुछ भाषाओं में, switch सिर्फ एक और if...else/if...else लिखने के रास्ता बनाना और प्रकार सीमित नहीं करते, अभिन्न प्रकार की जाँच की जा रही शायद क्योंकि, में तैयार किया जा रहा 90 का दशक, जो एक यथार्थवादी विकल्प बन गया। या शायद इसलिए कि जावास्क्रिप्ट के डिजाइनर (ब्रेंडन ईच) ने इसे इस तरह से पसंद किया।


नीचे, Baadshah पूछते हैं:

जिज्ञासा से बाहर: तो फिर अब कैसे अपने समर्थन स्ट्रिंग्स ??? क्या आप कृपया कुछ प्रकार का विचार दे सकते हैं?

 19: iload_2  
20: lookupswitch { // 3 
       1: 56 
       42: 67 
       67: 78 
      default: 89 
    } 
56: getstatic  #8 // Field java/lang/System.out:Ljava/io/PrintStream; 
59: ldc   #9 // String You used the special value one 
61: invokevirtual #10 // Method java/io/PrintStream.println:(Ljava/lang/String;)V 
64: goto   114 
67: getstatic  #8 // Field java/lang/System.out:Ljava/io/PrintStream; 
70: ldc   #11 // String You used the special value forty-two 
72: invokevirtual #10 // Method java/io/PrintStream.println:(Ljava/lang/String;)V 
75: goto   114 
78: getstatic  #8 // Field java/lang/System.out:Ljava/io/PrintStream; 
81: ldc   #12 // String You used the special value sixty-seven 
83: invokevirtual #10 // Method java/io/PrintStream.println:(Ljava/lang/String;)V 
86: goto   114 
89: getstatic  #8 // Field java/lang/System.out:Ljava/io/PrintStream; 
92: new   #13 // class java/lang/StringBuilder 
95: dup   
96: invokespecial #14 // Method java/lang/StringBuilder."":()V 
99: ldc   #15 // String You used the a non-special value 
101: invokevirtual #16 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 
104: iload_2  
105: invokevirtual #17 // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder; 
108: invokevirtual #18 // Method java/lang/StringBuilder.toString:()Ljava/lang/String; 
111: invokevirtual #10 // Method java/io/PrintStream.println:(Ljava/lang/String;)V

हम कार्रवाई में int पर तालिका देखने देख सकते हैं:

पहले, आइए थोड़ा रुकें और int मामले को देखो:

num = Integer.parseInt(args[0]); 
    switch (num) { 
     case 1: 
      System.out.println("You used the special value one"); 
      break; 
     case 42: 
      System.out.println("You used the special value forty-two"); 
      break; 
     case 67: 
      System.out.println("You used the special value sixty-seven"); 
      break; 
     default: 
      System.out.println("You used the a non-special value " + num); 
      break; 
    } 

कि इस तरह बाईटकोड पैदा करता है।

तो आप तारों के साथ ऐसा कैसे करते हैं? खैर, एक जवाब switch को if...else if...else संरचना में बदलना होगा। लेकिन वे उससे कहीं अधिक चतुर कुछ किया: वे hashCode इस्तेमाल किया अनुकूलन करने के लिए, और फिर equals इस्तेमाल किया टकराव के खिलाफ की रक्षा:

switch (str) { 
     case "abc": 
      System.out.println("You used the special value 'abc'"); 
      break; 
     case "def": 
      System.out.println("You used the special value 'def'"); 
      break; 
     case "ghi": 
      System.out.println("You used the special value 'ghi'"); 
      break; 
     default: 
      System.out.println("You used the a non-special value '" + str + "'"); 
      break; 
    } 

हो जाता है:

124: aload   4 
126: invokevirtual #19 // Method java/lang/String.hashCode:()I 
129: lookupswitch { // 3 
      96354: 164 
      99333: 180 
      102312: 196 
      default: 209 
    } 
164: aload   4 
166: ldc   #20 // String abc 
168: invokevirtual #21 // Method java/lang/String.equals:(Ljava/lang/Object;)Z 
171: ifeq   209 
174: iconst_0  
175: istore  5 
177: goto   209 
180: aload   4 
182: ldc   #22 // String def 
184: invokevirtual #21 // Method java/lang/String.equals:(Ljava/lang/Object;)Z 
187: ifeq   209 
190: iconst_1  
191: istore  5 
193: goto   209 
196: aload   4 
198: ldc   #23 // String ghi 
200: invokevirtual #21 // Method java/lang/String.equals:(Ljava/lang/Object;)Z 
203: ifeq   209 
206: iconst_2  
207: istore  5 
209: iload   5 
211: tableswitch { // 0 to 2 
       0: 236 
       1: 247 
       2: 258 
      default: 269 
    } 
236: getstatic  #8 // Field java/lang/System.out:Ljava/io/PrintStream; 
239: ldc   #24 // String You used the special value 'abc' 
241: invokevirtual #10 // Method java/io/PrintStream.println:(Ljava/lang/String;)V 
244: goto   299 
247: getstatic  #8 // Field java/lang/System.out:Ljava/io/PrintStream; 
250: ldc   #25 // String You used the special value 'def' 
252: invokevirtual #10 // Method java/io/PrintStream.println:(Ljava/lang/String;)V 
255: goto   299 
258: getstatic  #8 // Field java/lang/System.out:Ljava/io/PrintStream; 
261: ldc   #26 // String You used the special value 'ghi' 
263: invokevirtual #10 // Method java/io/PrintStream.println:(Ljava/lang/String;)V 
266: goto   299 
269: getstatic  #8 // Field java/lang/System.out:Ljava/io/PrintStream; 
272: new   #13 // class java/lang/StringBuilder 
275: dup   
276: invokespecial #14 // Method java/lang/StringBuilder."":()V 
279: ldc   #27 // String You used the a non-special value ' 
281: invokevirtual #16 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 
284: aload_3  
285: invokevirtual #16 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 
288: ldc   #28 // String ' 
290: invokevirtual #16 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 
293: invokevirtual #18 // Method java/lang/StringBuilder.toString:()Ljava/lang/String; 
296: invokevirtual #10 // Method java/io/PrintStream.println:(Ljava/lang/String;)V

देखें कि वे वहाँ क्या किया? यह मूल रूप से दो switches है: एक हैशकोड के आधार पर प्रत्येक मामले के लिए एक अद्वितीय संख्या प्राप्त करने के लिए (लेकिन equals के साथ डबल-चेकिंग), और फिर दूसरा प्रेषण करने के लिए।

+3

जिज्ञासा से बाहर: तो अब यह कैसे समर्थन स्ट्रिंग ??? क्या आप कृपया कुछ प्रकार का विचार दे सकते हैं? –

+1

@ बादाशाह: एक बहुत अच्छा सवाल! मैंने इसे संबोधित करने के लिए अद्यतन किया है। –

+0

धन्यवाद आप क्रॉडर। एक साधारण टिप्पणी के लिए उपयोगकर्ता स्पष्टीकरण। –

1

जेडीके 6 स्विच स्टेटमेंट चार, बाइट, int आदिम डेटा प्रकारों और enum पर काम किया। जेडीके 7 में उन्होंने महसूस किया कि java.lang.String भी स्थिर है और स्विच स्टेटमेंट द्वारा समर्थित डेटा प्रकारों की सूची में जोड़ा गया है।

उदाहरण के लिए निम्नलिखित कोड जेडीके 7 में ठीक काम करता है।

public static void OpenSource(String language) 
{ 
switch (language) { 
case "PERL": 
    System.out.println("PERL"); 
    break; 
case "Python": 
    System.out.println("Python"); 
    break; 
case "Ruby": 
    System.out.println("Ruby"); 
    break; 
case "PHP": 
    System.out.println("PHP"); 
    break; 
    default: 
    throw new IllegalArgumentException(); 
} 

}

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