单例模式不能仅靠静态方法实现,需私有构造、静态变量和加载机制协同;饿汉式线程安全但内存常驻,静态内部类式懒加载且线程安全,dcl式需volatile保障有序性。

直接用 Class 的静态方法本身不能实现单例模式——静态方法只是工具入口,真正起作用的是配合私有构造、静态变量和加载机制的一整套设计。所谓“利用 Class 静态方法”,实际是指通过一个 public static 方法(如 getInstance())作为唯一出口,来管控实例的创建与返回。
核心要点:静态方法只是门面,关键在三要素协同
一个可靠的单例,必须同时满足:
- 构造函数私有化(private Singleton()),杜绝外部 new
- 内部持有唯一实例的静态变量(private static Singleton instance)
- 提供 public static 方法统一返回该变量(public static Singleton getInstance())
饿汉式:静态方法直接返回预创建实例
类加载时就初始化好实例,静态方法只是“交出”它:
public class Singleton {
private static final Singleton instance = new Singleton(); // 类加载即创建
private Singleton() {}
public static Singleton getInstance() {
return instance; // 直接返回,无判断、无锁、线程安全
}
}
优点是简单、绝对线程安全;缺点是不管用不用,实例都占内存。
静态内部类式:静态方法触发延迟加载
把实例放在静态内部类里,靠 JVM 类加载机制保证懒加载 + 线程安全:
public class Singleton {
private Singleton() {}
private static class Holder {
static final Singleton instance = new Singleton();
}
public static Singleton getInstance() {
return Holder.instance; // 第一次调用才加载 Holder 类,仅一次
}
}
这是推荐的写法:不占初始内存、无同步开销、天然线程安全。
双重校验锁(DCL):静态方法里加判断和锁
兼顾懒加载与多线程安全,但需用 volatile 防止指令重排:
public class Singleton {
private static volatile Singleton instance;
private Singleton() {}
public static Singleton getInstance() {
if (instance == null) { // 第一重检查
synchronized (Singleton.class) {
if (instance == null) { // 第二重检查
instance = new Singleton(); // volatile 保证可见性与有序性
}
}
}
return instance;
}
}
适合对初始化时机敏感、且需严格控制资源占用的场景。
不复杂但容易忽略:静态方法本身没有魔法,它的价值在于封装了“何时创建”“如何保证唯一”“怎么防止并发冲突”的逻辑。选哪种实现,取决于你是否需要懒加载、是否在意内存、是否运行在高并发环境。











