黑马程序员技术交流社区

标题: 关于枚举中使用switch [打印本页]

作者: 翟宝海    时间: 2013-6-4 09:28
标题: 关于枚举中使用switch
  1. public class Test2
  2. {
  3.         public static void main(String[] args)
  4.         {
  5.                 ChangeLamp(TrafficLamp.GREEN);
  6.         }       
  7.         public static void ChangeLamp(TrafficLamp t)
  8.                 {
  9.                         switch(t)
  10.                         {
  11.                         case RED:
  12.                                 System.out.println("GREEN");
  13.                                 break;
  14.                         case GREEN:
  15.                                 System.out.println("YELLOW");
  16.                                 break;
  17.                         case YELLOW:
  18.                                 System.out.println("RED");
  19.                                 break;
  20.                         }
  21.                 }
  22.        
  23.         public enum TrafficLamp
  24.         {
  25.                 RED,GREEN,YELLOW;
  26.         }
  27. }
复制代码
switch语句的判断数据类型应该是byte short int char,为什么现在case后面也可以跟上枚举成员呢?
作者: 刘海芳    时间: 2013-6-4 09:50
我好想记得是:java在编译switch中的enum类型时,会把enum类型的所有元素转换陈一个数组,switch比较时,是比较数组的下标。好像是这样,仅作参考。附网上的给出的汇编代码(看都不懂的飘过....)
  1.   
  2. /*************************************
  3. *************************************
  4.                 源代码
  5. *************************************
  6. *************************************/  
  7. enum EnumTest {  
  8.     WINTER, SUMMER, SPRING, AUTUMN;  
  9. }  
  10. public static void testSwitchEnum() {  
  11.     EnumTest enumElement = EnumTest.AUTUMN;  
  12.     switch (enumElement) {  
  13.     case AUTUMN:  
  14.         System.out.println("AUTUMN");  
  15.         break;  
  16.     default:  
  17.         System.out.println("enum DEFAULT");  
  18.         break;  
  19.     }  
  20. }  
  21. /*************************************
  22. *************************************
  23.             enum类编译后的代码
  24. *************************************
  25. *************************************/  
  26. //enum其实也就是个普通的类,继承Enum  
  27. public final class EnumTest extends Enum  
  28. {  
  29.     private EnumTest(String s, int i)  
  30.     {  
  31.         super(s, i);      
  32.          
  33.         /*调用父类的构造函数
  34.         protected Enum(String name, int ordinal) {
  35.         this.name = name;    //名称
  36.         this.ordinal = ordinal;   元素位置
  37.         }
  38.         */  
  39.     }  
  40.     public static EnumTest[] values()  
  41.     {  
  42.         EnumTest aenumtest[];  
  43.         int i;  
  44.         EnumTest aenumtest1[];  
  45.         System.arraycopy(aenumtest = ENUM$VALUES, 0, aenumtest1 = new EnumTest[i = aenumtest.length], 0, i);  
  46.         return aenumtest1;  
  47.     }  
  48.     public static EnumTest valueOf(String s)  
  49.     {  
  50.         return (EnumTest)Enum.valueOf(meiju/EnumTest, s);  
  51.     }  
  52.     public static final EnumTest WINTER;  
  53.     public static final EnumTest SUMMER;  
  54.     public static final EnumTest SPRING;  
  55.     public static final EnumTest AUTUMN;  
  56.     private static final EnumTest ENUM$VALUES[];  
  57.     static   
  58.     {  
  59.         //enum的位置的排好的,想数组一样,enum元素最终都保存在ENUM$VALUES数组  
  60.         WINTER = new EnumTest("WINTER", 0);   
  61.         SUMMER = new EnumTest("SUMMER", 1);  
  62.         SPRING = new EnumTest("SPRING", 2);  
  63.         AUTUMN = new EnumTest("AUTUMN", 3);  
  64.         ENUM$VALUES = (new EnumTest[] {  
  65.             WINTER, SUMMER, SPRING, AUTUMN  
  66.         });  
  67.     }  
  68. }  
  69. /*************************************
  70. *************************************
  71.     testSwitchEnum方法编译后的代码
  72. *************************************
  73. *************************************/  
  74. 用到enum元素,所以会在当前类中多生成一个$SWITCH_TABLE$meiju$EnumTest()方法和$SWITCH_TABLE$meiju$EnumTest[]变量,用于switch  
  75. static int[] $SWITCH_TABLE$meiju$EnumTest()  
  76. {  
  77.     $SWITCH_TABLE$meiju$EnumTest;  
  78.     if($SWITCH_TABLE$meiju$EnumTest == null) goto _L2; else goto _L1  
  79. _L1:  
  80.     return;  
  81. _L2:  
  82.     JVM INSTR pop ;  
  83.     int ai[] = new int[EnumTest.values().length];  
  84.     try  
  85.     {  
  86.         ai[EnumTest.AUTUMN.ordinal()] = 4;  
  87.     }  
  88.     catch(NoSuchFieldError _ex) { }  
  89.     try  
  90.     {  
  91.         ai[EnumTest.SPRING.ordinal()] = 3;  
  92.     }  
  93.     catch(NoSuchFieldError _ex) { }  
  94.     try  
  95.     {  
  96.         ai[EnumTest.SUMMER.ordinal()] = 2;  
  97.     }  
  98.     catch(NoSuchFieldError _ex) { }  
  99.     try  
  100.     {  
  101.         ai[EnumTest.WINTER.ordinal()] = 1;  
  102.     }  
  103.     catch(NoSuchFieldError _ex) { }  
  104.     return $SWITCH_TABLE$meiju$EnumTest = ai;  
  105. }  
  106. private static int $SWITCH_TABLE$meiju$EnumTest[];//保存的是enum的index  
  107.   
  108. public static void testSwitchEnum()  
  109. {  
  110.     EnumTest enumElement = EnumTest.AUTUMN;  
  111.     //这个就是上面所用到的变量  
  112.     switch($SWITCH_TABLE$meiju$EnumTest()[enumElement.ordinal()])  
  113.     {  
  114.     case 4: // '/004'     因为enum类的元素其实就是个常量,在编译阶段就能确定值,在源代码的case AUTUMN:   其实也就被他所在的ordinal()给替换掉了,其实就是索引  
  115.         System.out.println("AUTUMN");  
  116.         break;  
  117.     default:  
  118.         System.out.println("enum DEFAULT");  
  119.         break;  
  120.     }  
  121. }  
  122.   
  123. /*************************************
  124. *************************************
  125.         用javap工具看class指令
  126. *************************************
  127. *************************************/  
  128. public static void testSwitchEnum();  
  129.   Code:  
  130.    Stack=2, Locals=1, Args_size=0  
  131.    0:   getstatic       #6; //Field meiju/EnumTest.AUTUMN:Lmeiju/EnumTest;  
  132.    3:   astore_0  
  133.    4:   getstatic       #7; //Field meiju/SwitchEnum$1.$SwitchMap$meiju$EnumTest  
  134. :[I  
  135.    7:   aload_0  
  136.    8:   invokevirtual   #8; //Method meiju/EnumTest.ordinal:()I  
  137.    11:  iaload  
  138.    12:  lookupswitch{ //1  
  139.                 1: 32;  
  140.                 default: 43 }  
  141.    32:  getstatic       #9; //Field java/lang/System.out:Ljava/io/PrintStream;  
  142.    35:  ldc     #10; //String AUTUMN  
  143.    37:  invokevirtual   #11; //Method java/io/PrintStream.println:(Ljava/lang/St  
  144. ring;)V  
  145.    40:  goto    51  
  146.    43:  getstatic       #9; //Field java/lang/System.out:Ljava/io/PrintStream;  
  147.    46:  ldc     #12; //String enum DEFAULT  
  148.    48:  invokevirtual   #11; //Method java/io/PrintStream.println:(Ljava/lang/St  
  149. ring;)V  
  150.    51:  return  
复制代码

作者: 杨增坤    时间: 2013-6-12 20:23
case的表达式可以是整数类型(int long char short )和String,枚举类型,同时case要与表达式的类型要对应(兼容)case后边的常量要互异,不重复!
作者: 曹秀云    时间: 2013-6-16 13:00
回个帖又不会怀孕!
作者: 曹秀云    时间: 2013-6-16 13:01
回个帖又不会怀孕!
作者: 清水    时间: 2013-6-19 18:29
1.5新特性
作者: 清水    时间: 2013-6-19 18:30
switch String 是1.7新特性, 建议不用(比如安卓开发用的是1.6的环境),知道就行




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2