【发布时间】:2020-09-24 17:53:36
【问题描述】:
看到answers like these,尝试通过comments澄清,对examples here不满意。
也许是时候回答这个具体问题了……
为什么将枚举单例实现称为lazy?
public enum EnumLazySingleton {
INSTANCE;
EnumLazySingleton() {
System.out.println("constructing: " + this);
}
public static void touchClass() {}
}
它与 eager 实施有何不同?
public class BasicEagerSingleton {
private static final BasicEagerSingleton instance = new BasicEagerSingleton();
public static BasicEagerSingleton getInstance() {
return instance;
}
private BasicEagerSingleton() {
System.out.println("constructing: " + this);
}
public static void touchClass() {}
}
两者都将在不访问 INSTANCE/getInstance() 的情况下初始化实例 - 例如拨打touchClass()。
public class TestSingleton {
public static void main(String... args) {
System.out.println("sleeping for 5 sec...");
System.out.println("touching " + BasicEagerSingleton.class.getSimpleName());
BasicEagerSingleton.touchClass();
System.out.println("touching " + EnumLazySingleton.class.getSimpleName());
EnumLazySingleton.touchClass();
}
}
输出:
sleeping for 5 sec...
touching BasicEagerSingleton
constructing: BasicEagerSingleton@7bfcd12c
touching EnumLazySingleton
constructing: INSTANCE
现在,我们可以说两者都是懒惰的。那么渴望是什么?
很明显(例如)“双重检查锁定”方式实际上是惰性的(并且混乱且缓慢)。但是如果 enum 是惰性的,那么由于不可避免的类加载,any 单例也是惰性的——事实上,一切都是惰性的。这种区别在什么时候会失去意义?
【问题讨论】:
-
我不太明白你的问题;这一切与
enum有什么关系?该类已实例化,因为您在该字段中有new调用,而不是(因为它更典型地用于单例)在getInstance中为if (instance == null) instance = new ...。 -
您的第一个带有枚举的代码并不比第二个代码更懒惰。
-
@khelwood 是的。这就是我的观点。为什么这是提供惰性单例的答案之一?
-
询问这些答案的作者。
-
在这个层面上没有意义,但是类加载细节在更深层次上有点不同,静态初始化需要一个内部类来获得与
enum相同的完全延迟加载效果已。但这只是理论上的,而且由于enum恰好使它变得简单有效,这是目前最好的方法。
标签: java enums singleton lazy-initialization double-checked-locking