我好想记得是:java在编译switch中的enum类型时,会把enum类型的所有元素转换陈一个数组,switch比较时,是比较数组的下标。好像是这样,仅作参考。附网上的给出的汇编代码(看都不懂的飘过....)-
- /*************************************
- *************************************
- 源代码
- *************************************
- *************************************/
- enum EnumTest {
- WINTER, SUMMER, SPRING, AUTUMN;
- }
- public static void testSwitchEnum() {
- EnumTest enumElement = EnumTest.AUTUMN;
- switch (enumElement) {
- case AUTUMN:
- System.out.println("AUTUMN");
- break;
- default:
- System.out.println("enum DEFAULT");
- break;
- }
- }
- /*************************************
- *************************************
- enum类编译后的代码
- *************************************
- *************************************/
- //enum其实也就是个普通的类,继承Enum
- public final class EnumTest extends Enum
- {
- private EnumTest(String s, int i)
- {
- super(s, i);
-
- /*调用父类的构造函数
- protected Enum(String name, int ordinal) {
- this.name = name; //名称
- this.ordinal = ordinal; 元素位置
- }
- */
- }
- public static EnumTest[] values()
- {
- EnumTest aenumtest[];
- int i;
- EnumTest aenumtest1[];
- System.arraycopy(aenumtest = ENUM$VALUES, 0, aenumtest1 = new EnumTest[i = aenumtest.length], 0, i);
- return aenumtest1;
- }
- public static EnumTest valueOf(String s)
- {
- return (EnumTest)Enum.valueOf(meiju/EnumTest, s);
- }
- public static final EnumTest WINTER;
- public static final EnumTest SUMMER;
- public static final EnumTest SPRING;
- public static final EnumTest AUTUMN;
- private static final EnumTest ENUM$VALUES[];
- static
- {
- //enum的位置的排好的,想数组一样,enum元素最终都保存在ENUM$VALUES数组
- WINTER = new EnumTest("WINTER", 0);
- SUMMER = new EnumTest("SUMMER", 1);
- SPRING = new EnumTest("SPRING", 2);
- AUTUMN = new EnumTest("AUTUMN", 3);
- ENUM$VALUES = (new EnumTest[] {
- WINTER, SUMMER, SPRING, AUTUMN
- });
- }
- }
- /*************************************
- *************************************
- testSwitchEnum方法编译后的代码
- *************************************
- *************************************/
- 用到enum元素,所以会在当前类中多生成一个$SWITCH_TABLE$meiju$EnumTest()方法和$SWITCH_TABLE$meiju$EnumTest[]变量,用于switch
- static int[] $SWITCH_TABLE$meiju$EnumTest()
- {
- $SWITCH_TABLE$meiju$EnumTest;
- if($SWITCH_TABLE$meiju$EnumTest == null) goto _L2; else goto _L1
- _L1:
- return;
- _L2:
- JVM INSTR pop ;
- int ai[] = new int[EnumTest.values().length];
- try
- {
- ai[EnumTest.AUTUMN.ordinal()] = 4;
- }
- catch(NoSuchFieldError _ex) { }
- try
- {
- ai[EnumTest.SPRING.ordinal()] = 3;
- }
- catch(NoSuchFieldError _ex) { }
- try
- {
- ai[EnumTest.SUMMER.ordinal()] = 2;
- }
- catch(NoSuchFieldError _ex) { }
- try
- {
- ai[EnumTest.WINTER.ordinal()] = 1;
- }
- catch(NoSuchFieldError _ex) { }
- return $SWITCH_TABLE$meiju$EnumTest = ai;
- }
- private static int $SWITCH_TABLE$meiju$EnumTest[];//保存的是enum的index
-
- public static void testSwitchEnum()
- {
- EnumTest enumElement = EnumTest.AUTUMN;
- //这个就是上面所用到的变量
- switch($SWITCH_TABLE$meiju$EnumTest()[enumElement.ordinal()])
- {
- case 4: // '/004' 因为enum类的元素其实就是个常量,在编译阶段就能确定值,在源代码的case AUTUMN: 其实也就被他所在的ordinal()给替换掉了,其实就是索引
- System.out.println("AUTUMN");
- break;
- default:
- System.out.println("enum DEFAULT");
- break;
- }
- }
-
- /*************************************
- *************************************
- 用javap工具看class指令
- *************************************
- *************************************/
- public static void testSwitchEnum();
- Code:
- Stack=2, Locals=1, Args_size=0
- 0: getstatic #6; //Field meiju/EnumTest.AUTUMN:Lmeiju/EnumTest;
- 3: astore_0
- 4: getstatic #7; //Field meiju/SwitchEnum$1.$SwitchMap$meiju$EnumTest
- :[I
- 7: aload_0
- 8: invokevirtual #8; //Method meiju/EnumTest.ordinal:()I
- 11: iaload
- 12: lookupswitch{ //1
- 1: 32;
- default: 43 }
- 32: getstatic #9; //Field java/lang/System.out:Ljava/io/PrintStream;
- 35: ldc #10; //String AUTUMN
- 37: invokevirtual #11; //Method java/io/PrintStream.println:(Ljava/lang/St
- ring;)V
- 40: goto 51
- 43: getstatic #9; //Field java/lang/System.out:Ljava/io/PrintStream;
- 46: ldc #12; //String enum DEFAULT
- 48: invokevirtual #11; //Method java/io/PrintStream.println:(Ljava/lang/St
- ring;)V
- 51: return
复制代码 |