枚举类型
枚举
基本使用
- 比较
使用enum
定义的枚举类是一种引用类型引用类型比较,要使用equals()
方法,如果使用==
比较,它比较的是两个引用类型的变量是否是同一个对象。因此,引用类型比较,要始终使用equals()
方法,但enum
类型可以例外。这是因为enum
类型的每个常量在JVM中只有一个唯一实例,所以可以直接用==
比较。
-
enum
定义的类型就是class
,只不过它有以下几个特点:- 定义的
enum
类型总是继承自java.lang.Enum
,且无法被继承; - 只能定义出
enum
的实例,而无法通过new
操作符创建enum
的实例; - 定义的每个实例都是引用类型的唯一实例;
- 可以将
enum
类型用于switch
语句。
- 定义的
-
编译器编译的结果
public enum Color {
RED, GREEN, BLUE;
}
编译后:
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构造方法,确保外部无法调用new操作符:
private Color() {}
}
- 代码
public class TestFile {
public static void main(String[] args) {
Weekday day = Weekday.SUN;
// 虽然是引用类型,但是可以直接用==比较
// 因为enum类型的每个常量在JVM中只有一个唯一实例
if (day == Weekday.SAT || day == Weekday.SUN) {
System.out.println("Work at home!");
} else {
System.out.println("Work at office!");
}
// 返回常量名
System.out.println(Weekday.TUE.name()); // TUE
// 返回定义的常量的顺序,从0开始计数
System.out.println(Weekday.TUE.ordinal()); // 1
// 自定义的属性
System.out.println(Weekday.TUE.value); // 2
System.out.println(Weekday.TUE.chinese); // 周二
// 重写toString()
System.out.println(Weekday.TUE); // 周二
// 迭代枚举元素
for (Weekday myVar : Weekday.values()) {
System.out.print(myVar);
}
System.out.println();
// 返回指定字符串值的枚举常量
System.out.println(Weekday.valueOf("MON")); // 周一
// 返回常量名
System.out.println(Weekday.valueOf(1).name()); // MON
switch(day) {
case MON:
case TUE:
case WED:
case THU:
case FRI:
System.out.println("Today is " + day + ". Work at office!");
break;
case SAT:
case SUN:
System.out.println("Today is " + day + ". Work at home!");
break;
default:
throw new RuntimeException("cannot process " + day);
}
}
enum Weekday {
MON(1, "周一"),
TUE(2, "周二"),
WED(3, "周三"),
THU(4, "周四"),
FRI(5, "周五"),
SAT(6, "周六"),
SUN(7, "周日");
// 枚举类的字段也可以是非final类型,即可以在运行期修改,但是不推荐这样做
public final int value;
private final String chinese;
// 定义private的构造方法(默认就是private),给每个枚举常量添加字段
Weekday(int value, String chinese) {
this.value = value;
this.chinese = chinese;
}
// 不重写返回的就是name()
@Override
public String toString() {
return this.chinese;
}
public static Weekday valueOf(int value){
switch (value){
case 1:
return MON;
case 2:
return TUE;
case 3:
return WED;
case 4:
return THU;
case 5:
return FRI;
case 6:
return SAT;
case 7:
return SUN;
default:
return null;
}
}
}
}
枚举+接口
public class Test {
public static void main(String[] args) {
System.out.println(judge("ROLE_ROOT_ADMIN"));
}
public static String judge(String roleName){
return RoleEnum.valueOf(roleName).operation();
}
}
interface RoleOperation {
String operation();
}
enum RoleEnum implements RoleOperation {
ROLE_ROOT_ADMIN {
@Override
public String operation() {
return "root";
}
},
ROLE_ORDER_ADMIN {
@Override
public String operation() {
return "order";
}
},
ROLE_NORMAL_ADMIN {
@Override
public String operation() {
return "normal";
}
};
}
设计模式中的枚举
单例模式
class Singleton {
// 私有
private Singleton() {
}
public static Singleton getInstance() {
return SingletonEnum.SEED.getINSTANCE();
}
enum SingletonEnum {
// 唯一的一个枚举对象
SEED;
private final Singleton INSTANCE;
SingletonEnum() {
// 实例化
INSTANCE = new Singleton();
}
public Singleton getINSTANCE() {
return INSTANCE;
}
}
}
策略模式
enum Calculator {
// 具体策略类
ADD {
@Override
public Double execute(Double x, Double y) {
return null;
}
},
MINUS {
@Override
public Double execute(Double x, Double y) {
return null;
}
};
// 策略方法
public abstract Double execute(Double x, Double y);
}
枚举集合
-
EnumSet<E extends Enum<E>> extends AbstractSet<E>
-
EnumMap<K extends Enum<K>, V> extends AbstractMap<K, V>