轻松入门枚举类Enum源码

本文详细解析了Java枚举类的内部实现,包括其构造函数、toString方法、equals方法等核心功能,以及如何通过valueOf方法获取枚举常量。同时,文章强调了枚举类的不可克隆性和不可序列化特性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、源码解读
public abstract class Enum<E extends Enum<E>> implements Comparable<E>, Serializable {
    /**
     * 枚举常量的名称
     * 使用toString方法访问此字段。
     */
    private final String name;
    /**
     * 返回此枚举常量的名称,与其枚举声明中声明的完全相同.
     * 大多数程序员应优先使用toString方法,因为toString方法可能会返回一个更加友好的名称。
     * 此方法主要用于特殊情况,其中正确性取决于获取确切名称,不会因发行版本而异。
     */
    public final String name() {
        return name;
    }
    /**
     * 枚举常量的序数(它指的是在枚举声明中的位置,其中初始常量的序数为零)。
     * 大多数程序员都不会使用这个字段。 它设计用于复杂的基于枚举型的数据结构,例如EnumSet,EnumMap。
	 */
	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();
    }
    /**
     * 抛出CloneNotSupportedException异常. 
     * 这能保证了枚举常量类永远不会被克隆,从而保证其为”单例”状态。
     */
    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对象. 
     * 当且仅当e1.getDeclaringClass()== e2.getDeclaringClass()时, 两个枚举常量e1和e2属于相同的枚举类型。
     */
    @SuppressWarnings("unchecked")
    public final Class<E> getDeclaringClass() {
        Class<?> clazz = getClass();
        Class<?> zuper = clazz.getSuperclass();
        return (zuper == Enum.class) ? (Class<E>)clazz : (Class<E>)zuper;
    }

    /**
     * 返回指定枚举类型的枚举常量指定的名称.  
     * 名称必须与声明此类型的枚举常量使用的标识符完全匹配(不允许使用无关的空格字符.)
     * 请注意,对于特定的枚举类型T,可以使用该枚举上隐式声明的valueOf(String)方法代替此方法从名称映射到相应的枚举常量。 
     * 枚举类型的所有常量都可以通过调用该类型的隐式方法 values()方法来获得。
     *
     * @param <T> 返回常量的枚举类型
     * @param  枚举常量类型enumType
     * @param  要返回的枚举常量的名称name
     * @return 返回具有指定名称和指定枚举类型的枚举常量
     * @throws 如果指定的枚举类型没有具有指定名称的常量,或者指定的类对象不表示枚举类型,抛出IllegalArgumentException 异常
     * @throws 如果enumType或者code name为null,NullPointerException异常
     */
    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");
    }    
}
二、实战例子
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值