Java enum

282 阅读2分钟

这是我参与8月更文挑战的第6天,活动详情查看:8月更文挑战

Java中enum (枚举)是个很有趣但经常被人忽略的东西。通过枚举可以将一组有限具名类型集中在一起创建一个新的类型,特别适用于表示字典、状态等场景。并且利用枚举的特性添加属性和方法可以很简单的实现一些设计模式如单例状态机等。

特性

定义枚举通过关键字enum,例如: image.png

枚举中每一个枚举项都可以看作是该类型的子类 image.png

添加属性和构造函数 image.png

添加方法 image.png

获取所有枚举项 image.png

根据名字获取枚举项 image.png

valueOf参数名必须和枚举项名称一致,否则会抛出异常

获取枚举项的序号(从0开始) image.png

实现接口

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();
}

image.png

枚举集合

枚举有两个专门存储枚举的集合EnumSetEnumMap

EnumSet

EnumSet继承了AbstractSet类,Set结构存储枚举值,并具有Set的方法 image.png

EnumSet 中的元素必须来自一个枚举类型

EnumMap

EnumMap继承了AbstractMap类,map结构存储枚举值,并具有map的方法。EnumMap要求key来自同一个枚举类型 image.png