枚举单例最简写法为public enum singleton { instance; },jvm保证其初始化原子线程安全、反射不可创建新实例、序列化返回唯一对象,支持字段方法但非严格懒加载。

枚举单例的写法就三行
Java 中用枚举实现单例,最简写法只需要定义一个枚举类,里面声明一个常量:
- public enum Singleton { INSTANCE; }
- INSTANCE 就是唯一的实例,JVM 在类加载阶段自动创建,且只创建一次
- 后续所有获取方式都是 Singleton.INSTANCE,返回的永远是同一个对象引用
为什么多线程下天然安全
枚举单例不需要加锁、也不依赖 volatile 或 synchronized,就能在并发场景下绝对安全,原因全在 JVM 层面:
- JVM 保证枚举类型的初始化是原子且线程安全的——多个线程同时首次访问 Singleton.class 时,只会有一个线程执行初始化,其余阻塞等待
- 枚举构造器被 JVM 特殊保护,反射调用
Constructor.newInstance()会直接抛IllegalArgumentException,无法绕过创建新实例 - 枚举类默认可序列化,反序列化时 JVM 强制返回已存在的 INSTANCE,不会生成新对象,无需手动实现
readResolve()
可以加字段和方法,不影响安全性
INSTANCE 不仅是个占位符,它本身就是一个完整对象,支持添加状态和行为:
Java Maven 项目审查工作流的通用输入处理。当 Java Maven 项目以 ZIP压缩包或 GitLab 仓库 URL 形式提供且需要...时使用。
- 可定义私有字段,比如
private String config = "prod"; - 可添加 public 方法,如
public void init() { ... }或public String getConfig() { return config; } - 所有线程通过 INSTANCE 调用方法,操作的是同一份数据,无同步冲突
注意它不是懒加载
枚举单例在类第一次被主动使用(如访问 INSTANCE 或调用其方法)时触发初始化,属于“按需加载”,但不是严格意义上的延迟到 getInstance() 调用才初始化——因为 INSTANCE 是 static final 的,加载即实例化。
如果业务要求启动时不加载(例如单例依赖外部资源且可能失败),枚举就不适合;否则,它比双重检查锁、静态内部类更简洁、更可靠。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










