人生有涯,学海无涯
一、概述
枚举就是一个语法糖成果。
定义一个枚举,其实就是定义一个继承抽象类Enum的类。
理解了Enum,就能理解枚举。
二、Enum解析
2.1 接口
public abstract class Enum<E extends Enum<E>>
implements Comparable<E>, Serializable {}
枚举类实现了Comparable和Serializable接口,那么也就意味着,每个枚举类都领有比拟(有序)和序列化性能。
2.2 属性
public abstract class Enum<E extends Enum<E>>
implements Comparable<E>, Serializable {
private final String name;
private final int ordinal;
public final String name() {
return name;
}
public final int ordinal() {
return ordinal;
}
}
这两个属性是枚举的内置属性,name示意的是枚举值的名称,ordinal示意的是枚举值的序号。
其作用前面再说
2.3 结构器
public abstract class Enum<E extends Enum<E>>
implements Comparable<E>, Serializable {
protected Enum(String name, int ordinal) {
this.name = name;
this.ordinal = ordinal;
}
}
Enum中只有这一个结构器,其申明为protected就是为了继承它的子类(咱们定义的各种枚举)来调用的。
2.4 equals办法
public abstract class Enum<E extends Enum<E>>
implements Comparable<E>, Serializable {
public final boolean equals(Object other) {
return this==other;
}
}
默认的equals办法底层就是应用==实现的,所以在枚举的比拟应用equals和==都是能够的。前提是没有在枚举类中重写equals办法。
咱们能够在自定义的枚举类中重写该办法,来实现咱们本人的比拟形式。
2.5 禁用的性能
public abstract class Enum<E extends Enum<E>>
implements Comparable<E>, Serializable {
protected final Object clone() throws CloneNotSupportedException {
throw new CloneNotSupportedException();
}
protected final void finalize() { }
private void readObject(ObjectInputStream in) throws IOException,
ClassNotFoundException {
throw new InvalidObjectException("can't deserialize enum");
}
private void readObjectNoData() throws ObjectStreamException {
throw new InvalidObjectException("can't deserialize enum");
}
}
这四个办法均是被禁用的办法:
- 克隆:目标为了保障单例惟一
- finalize:禁用终援用
- 序列化中禁用readObject和readObjectNoData办法:目标为了保障单例惟一
2.6 compareTo办法
public abstract class Enum<E extends Enum<E>>
implements Comparable<E>, Serializable {
public final int compareTo(E o) {
Enum<?> other = (Enum<?>)o;
Enum<E> self = this;
if (self.getClass() != other.getClass() && // optimization
self.getDeclaringClass() != other.getDeclaringClass())
throw new ClassCastException();
return self.ordinal - other.ordinal;
}
}
这是实现了接口Comparable中的办法。用于定义比拟的形式,能够看出这里是应用枚举值的序号作为比拟条件的。
2.7 办法
public abstract class Enum<E extends Enum<E>>
implements Comparable<E>, Serializable {
public static <T extends Enum<T>> T valueOf(Class<T> enumType,
String name) {
T result = enumType.enumConstantDirectory().get(name);
if (result != null)
return result;
if (name == null)
throw new NullPointerException("Name is null");
throw new IllegalArgumentException(
"No enum constant " + enumType.getCanonicalName() + "." + name);
}
}
该办法的作用是获取到指定枚举类型中指定枚举名称的枚举值。
三、枚举的实现
枚举是一种编译器语法糖。
咱们应用enum关键字定义一个枚举,编译之后,编译器会对其进行加工,具体如下:
- 编译成为class类型,并继承自Enum
- 增加动态的values办法,用于获取所有枚举值的数组
- 增加valueOf办法,实现Enum中的valueOf办法,能够依据具体的枚举值名称字符串获取对应的枚举值
- 增加公有结构器,其中调用Enum中定义的惟一的结构器
- 定义动态常量枚举值
- 增加动态块为这些动态枚举常量赋值
通过下面一些列加工之后,枚举类被解析为一个一般的类,类名不变。
四、Demo
public enum RedActiveStatusEnum {
NO_START("未开始", 1),
READY("筹备中", 2),
PROCESSING("进行中", 3),
END_NO_FINISH("已完结支付未实现", 4),
END_YES_FINISH("已完结支付实现", 5),
END_FORCE("强制完结", 6);
private String name;
private Integer value;
private RedActiveStatusEnum(String name, Integer value) {
this.name = name;
this.value = value;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getValue() {
return value;
}
public void setValue(Integer value) {
this.value = value;
}
public static void main(String[] args) {
RedActiveStatusEnum.END_FORCE.getValue();
}
}
发表回复