枚举类Enum反编译后效果

原代码

java 复制代码
// Singleton.java
public enum Singleton {
    INSTANCE;
    
    private String data = "Hello World";
    
    public void doSomething() {
        System.out.println("Doing something with: " + data);
    }
}

反编译后的结果

java 复制代码
// 反编译后的 Singleton 类
public final class Singleton extends java.lang.Enum<Singleton> {
    
    // 枚举实例 - 静态final常量
    public static final Singleton INSTANCE;
    
    
    // 静态代码块 - 在类加载时初始化枚举实例
    static {
        // 创建枚举实例,传入名称和序号
        INSTANCE = new Singleton("INSTANCE", 0);
        
        // 将所有枚举值放入数组
        $VALUES = new Singleton[]{INSTANCE};
    }

    // 私有字段
    private String data;
    
    // 私有构造方法 - 这是关键!
    private Singleton(String name, int ordinal) {
        // 调用父类Enum的构造方法
        super(name, ordinal);
        // 初始化实例字段
        this.data = "Hello World";
    }
    
    // 我们自定义的方法
    public void doSomething() {
        System.out.println("Doing something with: " + this.data);
    }

    
    // 自动生成的方法 - 获取所有枚举值
    public static Singleton[] values() {
        return (Singleton[])$VALUES.clone();
    }
    
    // 自动生成的方法 - 通过名称获取枚举值
    public static Singleton valueOf(String name) {
        return (Singleton)java.lang.Enum.valueOf(Singleton.class, name);
    }

    
    // 内部使用的数组
    private static final Singleton[] $VALUES;
}

为什么枚举是完美的单例

java 复制代码
1、final 类 - 无法被继承

public final class Singleton extends java.lang.Enum<Singleton>
// final 修饰符防止被继承,保护单例完整性


2、私有构造方法 - 防止外部实例化

private Singleton(String name, int ordinal)
// 构造方法是私有的,且接受两个参数(名称和序号)
// 这解释了为什么不能通过反射创建枚举实例:
// 反射需要知道确切的参数类型,但枚举的构造器是特殊的



3、静态代码块初始化 - 线程安全
static {
    INSTANCE = new Singleton("INSTANCE", 0);
    $VALUES = new Singleton[]{INSTANCE};
}
// JVM 保证静态代码块的线程安全
// 枚举实例在类加载时创建,且只创建一次


4、特殊的序列化处理
枚举的序列化机制是特殊的:
序列化时:只写入枚举的名称
反序列化时:通过 valueOf()方法根据名称获取已有的枚举实例
这保证了反序列化后仍然是同一个实例
相关推荐
IvanCodes3 小时前
Python 数据处理(十三):JSON、CSV 与数据序列化
开发语言·python
步行cgn4 小时前
Spring c 命名空间注入详解
java·后端·spring
明月_清风4 小时前
Maven 到底是什么?一篇文章搞懂 Java 项目构建与依赖管理
java·后端·maven
aramae4 小时前
MySQL复合查询(8)
java·c语言·开发语言·后端·算法
Rain的Java大神之路5 小时前
如何快速上传10G文件
java·spring boot·redis·后端·mysql·spring cloud·面试
Wang's Blog5 小时前
Java 接入Redis: 通用命令与键管理
java·服务器·redis
Wang's Blog6 小时前
Java 接入Redis: 列表集合与有序集合操作命令
java·服务器·redis
Ivanqhz6 小时前
SVD++算法
java·服务器·网络·深度学习·神经网络
qq_2518364577 小时前
springboot vue3 开发实现 拼豆管理系统
java·开发语言·ai编程
caoerzhong7 小时前
JeeWMS 开源仓库管理系统全景解读:一套 Java WMS 如何把 WMS/OMS/BMS/TMS 装进同一个系统
java·开源