黑马程序员技术交流社区
标题:
关于枚举中使用switch
[打印本页]
作者:
翟宝海
时间:
2013-6-4 09:28
标题:
关于枚举中使用switch
public class Test2
{
public static void main(String[] args)
{
ChangeLamp(TrafficLamp.GREEN);
}
public static void ChangeLamp(TrafficLamp t)
{
switch(t)
{
case RED:
System.out.println("GREEN");
break;
case GREEN:
System.out.println("YELLOW");
break;
case YELLOW:
System.out.println("RED");
break;
}
}
public enum TrafficLamp
{
RED,GREEN,YELLOW;
}
}
复制代码
switch语句的判断数据类型应该是byte short int char,为什么现在case后面也可以跟上枚举成员呢?
作者:
刘海芳
时间:
2013-6-4 09:50
我好想记得是: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
复制代码
作者:
杨增坤
时间:
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