参考: https://www.cnblogs.com/kailejun/p/6624471.html
一.概述
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");
网友评论