Enum浅析-JDK1.8
java.lang.Enum浅析
源码分析环境
- OS: Ubuntu 16.04 LTS X64
- IDE: IDEA 2017.1.3
- JDK:
- HotSpot™ 64-Bit JDK1.6
- HotSpot™ 64-Bit JDK1.7
- HotSpot™ 64-Bit JDK1.8
- OpenJDK 64-Bit Server VM (build 25.131-b11, mixed mode) OpenJDK1.8
一. Enum类的声明
public abstract class Enum<E extends Enum<E>>
implements Comparable<E>, Serializable{}
Enum 类是一个抽象类,不能直接实例化,需要有实现类。
使用了泛型,限定了只能是个 Enum 的子类型。
实现了 Comparable 接口,说明它是可以进行比较的,但是限定了只能跟 Enum 的子类型进行比较,但是限定了只能跟同一枚举类型的实例进行比较。
实现了可序列化接口,说明是支持序列化以及反序列化的
JDK1.5 的新特性
二. 构造方法
就一个构造方法,注意的是修饰符是 protected ,不允许外部通过构造方法直接实例化。
protected Enum(String name, int ordinal) {
this.name = name;
this.ordinal = ordinal;
}
三. Enum的属性
- 枚举常量的名字,注释上写着建议多使用toString() 方法,少使用这个字段。
private final String name;
- 枚举常量的序号,通常不直接使用。
private final int ordinal;
四. 方法都是些比较常见的
name
返回枚举的名称。
public final String name() {
return name;
}
ordinal
返回枚举的序号
public final int ordinal() {
return ordinal;
}
toString
默认返回枚举的名称。
public String toString() {
return name;
}
equals
比较两个枚举常量是否相同。
public final boolean equals(Object other) {
return this==other;
}
hashCode
返回枚举常量的哈希码。
public final int hashCode() {
return super.hashCode();
}
clone
这里的修饰符是 protected ,可以保证枚举是不能被 clone 的,单例。
protected final Object clone() throws CloneNotSupportedException {
throw new CloneNotSupportedException();
}
compareTo
用于跟别的类型进行比较,泛型限制了传入的就是枚举类型,返回的是一个 int 类型的值,就是使用两个枚举的序号进行相减,也就是使用数量进行相减操作,相等就返回 0 ,不相等就不等于 0。
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;
}
getDeclaringClass
返回枚举常量的类对象。
@SuppressWarnings("unchecked")
public final Class<E> getDeclaringClass() {
Class<?> clazz = getClass();
Class<?> zuper = clazz.getSuperclass();
return (zuper == Enum.class) ? (Class<E>)clazz : (Class<E>)zuper;
}
valueOf
根据名称返回特定枚举类型的枚举常量。
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);
}
readObject
防止默认的反序列化,私有的方法。
private void readObject(ObjectInputStream in) throws IOException,
ClassNotFoundException {
throw new InvalidObjectException("can't deserialize enum");
}
readObjectNoData方法
同上
private void readObjectNoData() throws ObjectStreamException {
throw new InvalidObjectException("can't deserialize enum");
}