Java学习笔记 (十七) 深入了解枚举

上一篇,枚举。

枚举是怎么实现的

可以通过反编译代码查看具体实现。
如下代码:

public enum  Season {
    SPRING,SUMMER,AUTUMN,WINTER;
}

反编译后,如下:
在这里插入图片描述
可以看见,反编译的后的代码继承了 java.lang.Enum 类,同时被 final修饰。
从这一点可以明白为什么枚举类不能继承别的类,以及为什么不能使用final关键字修饰,因为已经隐式的使用final修饰了。

Switch是怎么对枚举进行支持的

如下代码:

public  enum  Season {
    SPRING,SUMMER,AUTUMN,WINTER;

    static void getSeasonFeel(Season season){
        switch (season){
            case SPRING:
                System.out.println("春天到了,动物们开始交配了");
                break;
            case SUMMER:
                System.out.println("夏天到了,这是个赏心悦目的季节");
                break;
            case AUTUMN:
                System.out.println("天凉好个秋");
                break;
            case WINTER:
                System.out.println("被窝有粘性");
                break;
        }
    }
    public static void main(String []args){
        getSeasonFeel(Season.WINTER);
    }
}

反编译之后:
在这里插入图片描述
在这里插入图片描述
从上面两幅图可以看出,enum转换成了int类型了。
ordinal 方法是抽象类Enum的方法,该方法返回该枚举常量的序号。

   /**
     * Returns the ordinal of this enumeration constant (its position
     * in its enum declaration, where the initial constant is assigned
     * an ordinal of zero).
     *
     * Most programmers will have no use for this method.  It is
     * designed for use by sophisticated enum-based data structures, such
     * as {@link java.util.EnumSet} and {@link java.util.EnumMap}.
     *
     * @return the ordinal of this enumeration constant
     */
    public final int ordinal() {
        return ordinal;
    }

枚举与序列化

在枚举类型的序列化与反序列化上,Java做了特殊的规定:

Enum constants are serialized differently than ordinary serializable or externalizable objects. The serialized form of an enum constant consists solely of its name; field values of the constant are not present in the form. To serialize an enum constant, ObjectOutputStream writes the value returned by the enum constant’s name method. To deserialize an enum constant, ObjectInputStream reads the constant name from the stream; the deserialized constant is then obtained by calling the java.lang.Enum.valueOf method, passing the constant’s enum type along with the received constant name as arguments. Like other serializable or externalizable objects, enum constants can function as the targets of back references appearing subsequently in the serialization stream. The process by which enum constants are serialized cannot be customized: any class-specific writeObject, readObject, readObjectNoData, writeReplace, and readResolve methods defined by enum types are ignored during serialization and deserialization. Similarly, any serialPersistentFields or serialVersionUID field declarations are also ignored–all enum types have a fixedserialVersionUID of 0L. Documenting serializable fields and data for enum types is unnecessary, since there is no variation in the type of data sent.

序列化时 java 仅仅将枚举对象的name属性输出到结果中。
反序列化时 则是通过 Enum valueOf方法获取枚举对象。

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);
    }

参考资料

1.深度分析Java的枚举类型—-枚举的线程安全性及序列化问题深度分析Java的枚举类型—-枚举的线程安全性及序列化问题
2. 深入理解Java枚举类型(enum)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值