JDK源码之Enum类解析

一 概述

枚举类型是 JDK 5 之后引进的一种非常重要的引用类型,可以用来定义一系列枚举常量,使用 enum 来表示枚举可以更好地保证程序的类型安全和可读性
实际上在使用关键字enum创建枚举类型并编译后,编译器会为我们生成一个相关的类,这个类继承了Java API中的java.lang.Enum类,
也就是说通过关键字enum创建枚举类型在编译后事实上也是一个类类型而且该类继承自java.lang.Enum类

使用举例

public class EnumTest {

    enum MyCode{
        ONE("1","编码一"),
        TWO("2","编码二");

        private String code;
        private String name;

        MyCode(String code, String name) {
            this.code = code;
            this.name = name;
        }
    }

    public static void main(String[] args) {
        // 获取一个枚举实例
        MyCode one = MyCode.valueOf(MyCode.class, "ONE");
        // 可以调用Enum类中的实例方法
        one.compareTo(MyCode.TWO);
    }
}

二 源码分析

    public abstract class Enum<E extends Enum<E>>
            implements Comparable<E>, Serializable {

        //枚举常量的名称
        private final String name;

        //返回此枚举常量的名称,与其枚举声明中声明的完全相同
        public final String name() {
            return name;
        }

        //此枚举常量的序数(它在枚举声明中的位置,其中初始常量的序数为零)
        private final int ordinal;

        //返回序号
        public final int ordinal() {
            return ordinal;
        }

        // 构造器
        protected Enum(String name, int ordinal) {
            this.name = name;
            this.ordinal = ordinal;
        }

        //返回声明中包含的此枚举常量的名称
        public String toString() {
            return name;
        }

        //果指定的对象等于此枚举常量,则返回true。
        public final boolean equals(Object other) {
            return this==other;
        }

        public final int hashCode() {
            return super.hashCode();
        }

        // 无法被克隆
        protected final Object clone() throws CloneNotSupportedException {
            throw new CloneNotSupportedException();
        }

        //将此枚举与指定的枚举序号进行比较
        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;
        }

        //返回与此枚举常量的枚举类型相对应的Class对象
        @SuppressWarnings("unchecked")
        public final Class<E> getDeclaringClass() {
            Class<?> clazz = getClass();
            Class<?> zuper = clazz.getSuperclass();
            return (zuper == java.lang.Enum.class) ? (Class<E>)clazz : (Class<E>)zuper;
        }

        /**
         * 返回具有指定名称的指定枚举类型的枚举常量。
         * 该名称必须与用于声明此类型的枚举常量的标识符完全一致。
         * 请注意,对于特定枚举类型T ,
         *  有两个隐式声明方法可以直接使用:
         *      public static T valueOf(String)    根据名称获取单个枚举类型
         *      public static T[] values()   获取所有枚举类型数组
         */
        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);
        }

        //枚举类不能有 finalize 方法
        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");
        }
    }

猜你喜欢

转载自www.cnblogs.com/houzheng/p/13180751.html