Appearance
源码:labs/java/runtime-concurrency/singleton-dcl/src/InnerClassSingleton.java
- 原始路径:
labs/java/runtime-concurrency/singleton-dcl/src/InnerClassSingleton.java - 类型:
java
java
/**
* 静态内部类(Holder)单例。
*
* 特点:
* - 懒加载:首次 getInstance() 才加载 Holder,触发 static 字段初始化
* - 线程安全:✅ JVM 类初始化 <clinit> 互斥,天然只执行一次
* - 性能:⚡ 无锁,创建后 get 仅为字段读取
* - 复杂度:低,无 volatile / 双重检查,Java/Android 工程首选之一
*
* Java 场景:
* - ✅ 无参、默认配置的全局单例(Effective Java 与 DCL 并列推荐)
* - ✅ 不想在类加载主类时就创建实例,又要避免 DCL 手写错误
* - ❌ 构造需要外部传参时 HOLDER 里无法灵活注入,应改用 DCL 或工厂 + DI
*
* Android 场景:
* - ✅ 无 Context 或仅用 Application Context 的全局管理器(网络门面、缓存协调)
* - ✅ 比 enum 更常出现在业务代码:懒加载、不抢 Application 启动时机
* - 与 Hilt @Singleton 并存时,新代码优先 DI;Holder 适合无框架的 Java 模块
* - 仍禁止持有 Activity Context,否则进程级单例导致泄漏
*
* 原理:
* - 外部类加载不会初始化 Holder;第一次 getInstance() → 加载 Holder → new 一次
*
* 如何运行:
* - javac -d out src/*.java
* - java -cp out InnerClassSingleton
*
* 预期输出:
* - 两次输出同一个对象引用,same instance = true
*/
public class InnerClassSingleton {
private InnerClassSingleton() {
}
private static class Holder {
private static final InnerClassSingleton INSTANCE = new InnerClassSingleton();
}
public static InnerClassSingleton getInstance() {
return Holder.INSTANCE;
}
public static void main(String[] args) {
InnerClassSingleton a = InnerClassSingleton.getInstance();
InnerClassSingleton b = InnerClassSingleton.getInstance();
System.out.println(a);
System.out.println(b);
System.out.println("same instance = " + (a == b));
}
}