Java枚举使用


一.概述

1.历史
  • 枚举与泛型、for-each等特性在JDK1.5时引进
  • JDK1.6后switch语句支持枚举类型
2.枚举与常量类
  • 枚举型可以直接存入数据库varchar类型字段,存入数据为枚举的常量名
  • 枚举在编译期限定类型,与int、String等类型比在switch语句中不会发生越界
  • 使用常量类时需要通过equals判断两者是否相等,枚举由于值唯一,可以通过==判断,提高性能
  • 改变常量值对引用类是否影响:常量类编译时直接将常量的值编译到引用常量的类的二进制代码,常量的值在升级变化后,需要重新编译引用常量的类,否则里面的常量值不会更新;枚举则没有将常量值编译到引用枚举类的代码中,即使枚举的常量值发生变化,也不会影响引用枚举常量的类
  • 是否可被继承:枚举类编译后默认为final class,不允许继承以防止被子类修改;而常量类可以被继承修改、增加字段

二.源码及反编译

1.基础版
  • 源代码
public enum ColorEnum {
    RED,BLUE,GREEN
}
  • 反编译代码
public final class ColorEnum extends Enum
{

    //返回存储枚举实例的数组的副本。values()方法通常用于foreach循环遍历枚举常量。
    public static ColorEnum[] values()
    {
        return (ColorEnum[])$VALUES.clone();
    }
    //根据实例名获取实例
    public static ColorEnum valueOf(String s)
    {
        return (ColorEnum)Enum.valueOf(ColorEnum, s);
    }

    //私有构造方法,这里调用了父类的构造方法,其中参数s对应了常量名,参数i代表枚举的一个顺序(这个顺序与枚举的声明顺序对应,用于oridinal()方法返回顺序值)
    private ColorEnum(String s, int i)
    {
        super(s, i);
    }

    //我们定义的枚举在这里声明了三个 ColorEnum的常量对象引用,对象的实例化在static静态块中
    public static final ColorEnum RED;
    public static final ColorEnum BLUE;
    public static final ColorEnum GREEN;
    //将所有枚举的实例存放在数组中
    private static final ColorEnum $VALUES[];

    static 
    {
        RED = new ColorEnum("RED", 0);
        BLUE = new ColorEnum("BLUE", 1);
        GREEN = new ColorEnum("GREEN", 2);
        //将所有枚举的实例存放在数组中
        $VALUES = (new ColorEnum[] {
            RED, BLUE, GREEN
        });
    }
}
  • 注意
    1)枚举的构造方法私有,不允许通过构造方法创建枚举实例
    2)枚举在类初始化时通过静态代码块创建枚举实例
    3)实际上枚举类是以一般Java类实现,不过Java编译器做了枚举类的语法解析和编译
2.进阶版
  • 源代码
public enum ColorEnum {
    RED("red","红色"),GREEN("green","绿色"),BLUE("blue","蓝色");
    //防止字段值被修改,增加的字段也统一final表示常量
    private final String key;
    private final String value;

    private ColorEnum(String key,String value){
        this.key = key;
        this.value = value;
    }
    //根据key获取枚举
    public static ColorEnum getEnumByKey(String key){
        if(null == key){
            return null;
        }
        for(ColorEnum temp:ColorEnum.values()){
            if(temp.getKey().equals(key)){
                return temp;
            }
        }
        return null;
    }
    public String getKey() {
        return key;
    }
    public String getValue() {
        return value;
    }
}
  • 反编译代码:注意static静态块和构造方法的变化
public final class ColorEnum extends Enum
{

    public static ColorEnum[] values()
    {
        return (ColorEnum[])$VALUES.clone();
    }

    public static ColorEnum valueOf(String s)
    {
        return (ColorEnum)Enum.valueOf(ColorEnum, s);
    }

    //构造方法在原基础上加上我们新增的两个形参
    private ColorEnum(String s, int i, String s1, String s2)
    {
        super(s, i);
        key = s1;
        value = s2;
    }

    //自定义方法,通过key值获得对应的枚举对象
    public static ColorEnum getEnumByKey(String s)
    {
        if(null == s)
            return null;
        ColorEnum acolorenum[] = values();
        int i = acolorenum.length;
        for(int j = 0; j < i; j++)
        {
            ColorEnum colorenum = acolorenum[j];
            if(colorenum.getKey().equals(s))
                return colorenum;
        }

        return null;
    }

    public String getKey()
    {
        return key;
    }

    public String getValue()
    {
        return value;
    }

    public static final ColorEnum RED;
    public static final ColorEnum GREEN;
    public static final ColorEnum BLUE;
    //我们自定义的两个字段
    private final String key;
    private final String value;
    private static final ColorEnum $VALUES[];

    static 
    {
        RED = new ColorEnum("RED", 0, "red", "\u7EFE\u3223\u58CA");
        GREEN = new ColorEnum("GREEN", 1, "green", "\u7F01\u80EF\u58CA");
        BLUE = new ColorEnum("BLUE", 2, "blue", "\u9483\u6FCA\u58CA");
        $VALUES = (new ColorEnum[] {
            RED, GREEN, BLUE
        });
    }
}

三.其他

1.常用方法
  • values():获取枚举中所有常量实例的数组,常配合foreach完成遍历
for(ColorEnum temp:ColorEnum.values())  {
     system.out.println(temp);
}
//返回
RED
GREEN
BLUE
  • valueOf():通过枚举常量名获取枚举实例
ColorEnum red = ColorEnum.valueOf("RED");

文章作者: jackey
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 jackey !
评论
  目录