这是我参与8月更文挑战的第6天,活动详情查看:8月更文挑战
Java中enum (枚举)是个很有趣但经常被人忽略的东西。通过枚举可以将一组有限具名类型集中在一起创建一个新的类型,特别适用于表示字典、状态等场景。并且利用枚举的特性添加属性和方法可以很简单的实现一些设计模式如单例、状态机等。
特性
定义枚举通过关键字enum,例如:
枚举中每一个枚举项都可以看作是该类型的子类
添加属性和构造函数
添加方法
获取所有枚举项
根据名字获取枚举项
valueOf参数名必须和枚举项名称一致,否则会抛出异常
获取枚举项的序号(从0开始)
实现接口
public interface Log {
void log();
}
@Getter
@AllArgsConstructor
public enum ColorEnum implements Log {
GREEN("绿色"){
@Override
public void log() {
System.out.println(this.getName());
}
},
YELLOW("黄色"){
@Override
public void log() {
System.out.println(this.getName());
}
},
RED("红色"){
@Override
public void log() {
System.out.println(this.getName());
}
};
private final String name;
}
所有的
enum都继承自Java.lang.Enum类。由于 Java 不支持多重继承,所以自定义的枚举类不能再继承其他类。但是可以实现接口
应用
单例
枚举是最优雅的实现单例模式的方式。枚举可以通过JVM保证线程安全和单一实例。
public class User {
private String userName;
// 获取单例对象
public static User getUser() {
return SingletonEnum.INSTANCE.getUser();
}
@Getter
enum SingletonEnum {
INSTANCE;
private User user;
// 利用枚举的特性保证单例
SingletonEnum() {
user = new User();
}
}
}
状态机
枚举类型非常适合用来创建状态机。使用枚举项列举出所有的状态,在通过添加自定义方法的方式定义状态的流转
@Getter
@AllArgsConstructor
public enum ItemStatusEnum {
WAIT_PAYMENT("待支付"){
@Override
ItemStatusEnum next() {
return WAIT_DELIVER;
}
},
WAIT_DELIVER("待发货"){
@Override
ItemStatusEnum next() {
return WAIT_RECEIVE;
}
},
WAIT_RECEIVE("待收货"){
@Override
ItemStatusEnum next() {
return FINISH;
}
},
FINISH("已完成"){
@Override
ItemStatusEnum next() {
throw new RuntimeException("没有下个状态了");
}
};
private String name;
abstract ItemStatusEnum next();
}
枚举集合
枚举有两个专门存储枚举的集合EnumSet和EnumMap
EnumSet
EnumSet继承了AbstractSet类,Set结构存储枚举值,并具有Set的方法
EnumSet 中的元素必须来自一个枚举类型
EnumMap
EnumMap继承了AbstractMap类,map结构存储枚举值,并具有map的方法。EnumMap要求key来自同一个枚举类型