使用enum
来定义枚举类:
enum Weekday {
SUN, MON, TUE, WED, THU, FRI, SAT; //依次列出枚举的常量名
}
class test {
public static void main(String[] args) {
Weekday day = Weekday.SUN; //为枚举类型
if (day == Weekday.SUN) { }
}
}
使用enum定义的枚举类是一种引用类型。通常情况下,引用类型进行比较要使用equals()方法,如果使用==比较,它比较的是两个引用类型的变量是否是同一个对象。
但enum类型可以例外,因为enum类型的每个常量在JVM中只有一个唯一实例,所以可以直接用==
比较。
enum
定义的类型本质上就是class,它的独特之处是:
- 定义的enum类型总是继承自java.lang.Enum,且无法被继承
- 只能定义出enum的实例,而无法通过new操作符创建enum的实例
- 定义的每个实例都是引用类型的唯一实例
- 可以将enum类型用于
switch
语句
枚举类天生具有类型信息和有限个枚举常量,非常适合用于switch语句
例如,定义的Color枚举类:
public enum Color {
RED, GREEN, BLUE;
}
编译器编译出的class大概就像这样:
public final class Color extends Enum { // 继承自Enum,标记为final class
public static final Color RED = new Color(); // 枚举变量其实是一个实例
public static final Color GREEN = new Color(); // 每个实例均为全局唯一:
public static final Color BLUE = new Color();
private Color() {} // private构造方法,确保外部无法调用new操作符
...
}
枚举类的创建本质:
enum {
//SUN, MON, TUE, WED, THU, FRI, SAT;
//SUN(3), MON(1), TUE(4), WED(0), THU(2), FRI(5), SAT(6);
//MON(1, "星期一"), TUE(2, "星期二"), WED(3, "星期三"), THU(4, "星期四"), FRI(5, "星期五"), SAT(6, "星期六"), SUN(0, "星期日");
//本质上是调用构造函数创建了一个实例对象
}
简写 | 实际核心代码 |
---|---|
SUN |
Weekday SUN = new Weekday() |
SUN(3) |
Weekday SUN = new Weekday(3) |
SUN(3, "星期日") |
Weekday SUN = new Weekday(3, "星期日") |
因此也可以自己给enum编写构造方法、变量和方法。
(enum的构造方法要声明为private,变量强烈建议声明为final)
enum
类中还有一些实例函数:
-
name()
:将枚举量转换为字符串,返回字符串
String s = Weekday.SUN.name(); // "SUN"
-
ordinal()
:返回定义的常量的顺序(即转为int型),默认从0开始计数
int n = Weekday.MON.ordinal(); // 1
如果想要指定每个枚举常量对应的int型数字,可以自定义构造函数为:
enum Weekday {
SUN(3), MON(1), TUE(4), WED(0), THU(2), FRI(5), SAT(6);
public final int value;
private Weekday(int value) {
this.value = value;
}
}
class test {
public static void main(String[] args) {
Weekday day = Weekday.SUN;
System.out.println(day.value);
}
}
如此即使枚举常量的顺序改变,其对应的int值仍不会变,提高了代码的健壮性。
-
toString()
:默认情况下,对枚举常量调用toString()会和name()一样返回相同的字符串。但是,toString()
可以被重写,而name()则不行
class test {
public static void main(String[] args) {
Weekday day = Weekday.SUN;
System.out.println(day.name()); //SUN
System.out.println(day.toString()); //星期日
System.out.println("Today is " + day); //Today is 星期日
//引用类型转化为字符串时,会自动调用toString()方法
}
}
enum Weekday {
MON(1, "星期一"), TUE(2, "星期二"), WED(3, "星期三"), THU(4, "星期四"), FRI(5, "星期五"), SAT(6, "星期六"), SUN(0, "星期日");
public final int dayValue;
private final String chinese;
private Weekday(int dayValue, String chinese) { //构造函数
this.dayValue = dayValue;
this.chinese = chinese;
}
@Override
public String toString() { //重写toString函数
return this.chinese;
}
}
重写toString()的目的是在输出时更有可读性。
注意:判断枚举常量的名字时,要始终使用name()方法,绝不能调用toString()!