用法
在JDK 1.5之前通常用final来定义各种常量,现在新加了枚举类型,最简单的用法如下:
enum Color {
RED,
GREEN
}
还可以像普通的类那样自己定义属性和方法:
enum Color {
RED("red"),
GREEN("green");
String name;
Color(String name) {
this.name = name;
}
public String toString(){
return name;
}
}
甚至enum还可以去实现接口:
enum Color implements Comparable<Color> {
RED,
GREEN;
}
在使用的时候,枚举可以用来比较:
Color c = Color.RED;
if(c == Color.GREEN){
// ...
}
也可以用来switch:
Color c = Color.RED;
switch (c) {
case RED:
case GREEN:
}
而且你可以很方便的变量一个枚举类型中所有的属性:
for (Color c : Color.values()) {
System.out.println(c);
}
甚至在你只知道枚举的变量名的时候也能拿到对应的属性:
System.out.println(Color.valueOf("RED"));
枚举VS常量
首先不同的枚举类是不同的类型,而你用final static修饰的一般都是int等基本类型,这样的常量不容易做到类型检查,这也算是一个枚举的优势:
public static void check(Color c){
}
如果你想封装一种类型的常量类型检查的话(除非有现成的类),为什么不用enum?
enum到底是什么
在编译之后会有一个Color.class文件,使用javap查看:
final class Color extends java.lang.Enum implements java.lang.Comparable{
public static final Color RED;
public static final Color GREEN;
public static Color[] values();
public static Color valueOf(java.lang.String);
static {};
}
该类继承自:
java.lang.Enum
然后通过javap -c Color来看初始化的代码:
static {};
Code:
0: new #4; //class Color
3: dup
4: ldc #7; //String RED
6: iconst_0
7: invokespecial #8; //Method "<init>":(Ljava/lang/String;I)V
10: putstatic #9; //Field RED:LColor;
13: new #4; //class Color
16: dup
17: ldc #10; //String GREEN
19: iconst_1
20: invokespecial #8; //Method "<init>":(Ljava/lang/String;I)V
23: putstatic #11; //Field GREEN:LColor;
26: iconst_2
27: anewarray #4; //class Color
30: dup
31: iconst_0
32: getstatic #9; //Field RED:LColor;
35: aastore
36: dup
37: iconst_1
38: getstatic #11; //Field GREEN:LColor;
41: aastore
42: putstatic #1; //Field $VALUES:[LColor;
45: return
这里大家可能会对枚举switch有疑问,我们写代码来看下:
public class Test {
public void func(Color c){
switch(c){
case RED:
case GREEN:
}
}
}
然后用javap -c查看,得到:
public void func(Color);
Code:
0: getstatic #2; //Field Test$1.$SwitchMap$Color:[I
3: aload_1
4: invokevirtual #3; //Method Color.ordinal:()I
7: iaload
8: lookupswitch{ //2
1: 36;
2: 36;
default: 36 }
36: return
}
可以看到这里switch的其实还是enum类中的ordinal(int),和之前我们对switch的认识是一致的。----------END----------