枚举

本文详细探讨了Java枚举的特点及其实现机制,包括枚举的单例特性、多态用法、switch语句中的应用,以及EnumSet和EnumMap等高级特性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

enum 的特征

public enum ColorEnum {
    RED("红色"),
    BLUE("蓝色"),
    GREEN("绿色"),
    ;
    private String description;
    private static Random random = new Random(4l);

    ColorEnum(String description){
        this.description = description;
    }
    public String getDescription() {
        return description;
    }

    @Override
    public String toString(){
        return "enum:" + this.name();
    }

    public static ColorEnum next(){
        return values()[random.nextInt(values().length)];
    }

    public static void main(String[] args){
        // 1.values()
        for(ColorEnum colorEnum : ColorEnum.values()) {
            // 2.name() 与 toString() 
            System.out.print(colorEnum.name() + " ");
            System.out.print(colorEnum + " ");
            System.out.print(colorEnum.getDescription() + " ");
            // 3.ordinal()
            System.out.println(colorEnum.ordinal());
        }
        ColorEnum colorEnum = ColorEnum.next();
        // 4.valueOf()
        ColorEnum colorEnum1 = ColorEnum.valueOf(colorEnum.name());
        // 5.单例,equals 和 == 结果相同
        System.out.println(colorEnum == colorEnum1);
        System.out.println(colorEnum.equals(colorEnum1));
        // 6.getDeclaringClass()
        System.out.println(colorEnum.getDeclaringClass());
        // 7.compareTo() 声明顺序比较
        System.out.println(colorEnum.compareTo(RED));
        System.out.println(colorEnum.compareTo(BLUE));
        System.out.println(colorEnum.compareTo(GREEN));
        // 8.getEnumConstants() 
        ColorEnum[] values = ColorEnum.class.getEnumConstants();
    }
}
  • name() 一定返回枚举定义时的名称,toString 默认情况下与 name() 相同,但是在子类中 toString 可以覆盖,而 name() 是 final 的。
  • 枚举的实现是单例的,但是还是使用 equals 养成良好习惯。

神奇的 enum

将上一个例子编译后的 .class 文件进行反编译后,会看到一些有趣的问题:

Compiled from "ColorEnum.java"
public final class lirui.ColorEnum extends java.lang.Enum<lirui.ColorEnum> {
  public static final lirui.ColorEnum RED;
  public static final lirui.ColorEnum BLUE;
  public static final lirui.ColorEnum GREEN;
  public static lirui.ColorEnum[] values();
  public static lirui.ColorEnum valueOf(java.lang.String);
  public java.lang.String getDescription();
  public static lirui.ColorEnum next();
  public java.lang.String toString();
  public static void main(java.lang.String[]);
  static {};
}
  1. 编译器为类声明添加了 final,并且继承了 Enum 类,所以编写枚举类时不能在继承其他类,但是可以实现接口。
  2. 编译器添加了 static final 的枚举对象,这也是我们平时可以使用 ColorEnum.RED 获取枚举实例的原因。所以枚举实现是单例的。
  3. 编译器添加了 values(),valueOf() 这两个方法,而对于他的父类 Enum 也有一个valueOf(),不过两者参数不同,并不是同一个方法。
  4. 将 ColorEnum 向上转型为 Enum 时,values() 方法将失效,但是可以使用 Class 上的 getEnumConstants() 获取所有 enum 实例。

enum 的多态

  • Java 允许为 enum 实例编写方法,可以为 enum 定义一个或多个 abstract 方法,然后为每个 enum 实例实现该抽象方法。
public enum ColorEnum{
    RED("红色"){
        public String getName(){
            return "红色";
        }
    },
    BLUE("蓝色"){
        public String getName(){
            return "蓝色";
        }

    },
    GREEN("绿色") {
        String getName() {
            return "绿色";
        }
    },
    ;
    private String description;
    private static Random random = new Random(4);

    abstract String getName();

    ColorEnum(String description){
        this.description = description;
    }
    public String getDescription() {

        return description;
    }

    @Override
    public String toString(){
        return "enum:" + this.name();
    }

    public static ColorEnum next(){
        return values()[random.nextInt(values().length)];
    }


    public static void main(String[] args){

        for(ColorEnum colorEnum : ColorEnum.values()) {
            System.out.println(colorEnum.getName());
        }
    }
}
  • 还可以在enum 实例中覆盖 enum 定义的方法。
public enum ColorEnum{
    RED("红色"){
        public String getName(){
            return "红色";
        }
    },
    BLUE("蓝色"){
        public String getName(){
            return "蓝色";
        }

    },
    GREEN("绿色") {
        public String getName() {
            return "绿色";
        }
    },
    ;
    private String description;
    private static Random random = new Random(4);

    public String getName(){
        return "颜色";
    }

    ColorEnum(String description){
        this.description = description;
    }
    public String getDescription() {

        return description;
    }

    @Override
    public String toString(){
        return "enum:" + this.name();
    }

    public static ColorEnum next(){
        return values()[random.nextInt(values().length)];
    }


    public static void main(String[] args){

        for(ColorEnum colorEnum : ColorEnum.values()) {
            System.out.println(colorEnum.getName());
        }
    }
}

switch 中使用 enum

public static String getName(ColorEnum colorEnum){
        switch (colorEnum){
            case RED: return "红色";
            case BLUE: return "蓝色";
            case GREEN: return "绿色";
            default: return null;
        }
    }

EnumSet

  • EnumSet 是为了通过 enum 创建一种替代品,以替代传统的基于 int 的 “位标志”,可以用来表示一些开关信息
  • EnumSet 设计时充分考虑的性能,内部将一个 long 值作为比特向量,并且具有很好的表达能力。如果 enum 实例的数量超过了 64(long 的长度)个,会再增加一个 long 。

EnumMap

EnumMap 是一个特殊的 map, 他要求其中的键必须来自一个 enum。由于 enum 的数量有限,所以 Enum 内部可以使用数组实现,所以它的速度也非常快。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值