七的博客

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 类是一个抽象类,不能直接实例化,需要有实现类。

  • 使用了泛型,限定了只能是个 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");
    }