我按照本教程创建了Singleton,并且所有者在http://www.journaldev.com/1377/java-singleton-design-pattern-best-practices-examples
下面的方法时发表了评论public class EagerInitializedSingleton {
private static final EagerInitializedSingleton instance = new EagerInitializedSingleton();
//private constructor to avoid client applications to use constructor
private EagerInitializedSingleton(){}
public static EagerInitializedSingleton getInstance(){
return instance;
}
}
如果您的单例类没有使用大量资源,那就是 使用方法。但在大多数场景中,Singleton类都是 为文件系统,数据库连接等资源创建 并且除非客户端调用,否则我们应该避免实例化 getInstance方法。
问题是:
他们说我们应该避免实例化,除非客户端调用getInstance方法
但正如我在此代码中所知,实例化(对象实例)总是在类EagerInitializedSingleton
加载时发生,EagerInitializedSingleton
仅在我们调用EagerInitializedSingleton.getInstance()
时加载
=>实例化将在getInstance()
时及时getInstance()
参考:
静态变量仅在执行开始时初始化一次(当Classloader第一次加载类时)。 (来自https://stackoverflow.com/a/8704607/5381331)
那么什么时候加载课程?
恰好有两种情况:
- 执行新字节码时(例如,FooClass f = new FooClass();)
- 当字节码对类进行静态引用时(例如,System.out)
(来自http://www.javaworld.com/article/2077260/learn-java/learn-java-the-basics-of-java-class-loaders.html)
我错了还是错了。请给我一些消息。
答案 0 :(得分:2)
在这种特定代码的情况下,您可能正确。
但是,如果static
的{{1}}方法,或EagerInitializedSingleton
非static
成员final
在您的代码库中某处引用调用EagerInitializedSingleton
时,getInstance
的{{1}}变量将初始化。
与instance
课程EagerInitializedSingleton
的反思性调用相同。
注意(并且原谅显而易见的是)有一些声明单例的替代方法,包括延迟初始化或枚举。
答案 1 :(得分:1)
我认为问题是当一个类被加载而不需要获取实例时,但是出于其他原因。您假设当用户想要获取该单例的实例时,将首次使用该类,但是由于某些其他原因可能会发生这种情况,他可能只是为了某些东西调用类加载器,或者使用某些第三方软件来验证类,任何想到加载类但没有得到单例实例的东西。
答案 2 :(得分:1)
他们说除非客户打电话,否则我们应该避免实例化 getInstance方法
解决方案是延迟加载。 来自wikipedia, Initialization-on-demand holder idiom
当JVM加载类Something时,该类将通过 初始化。由于该类没有任何静态变量 初始化,初始化完成很简单。静态类 其中的定义LazyHolder直到JVM才初始化 确定必须执行LazyHolder。静态类 LazyHolder仅在静态方法getInstance为时执行 在类Something上调用,第一次发生这种情况 JVM将加载并初始化LazyHolder类。
public class Something {
private Something() {}
private static class LazyHolder {
private static final Something INSTANCE = new Something();
}
public static Something getInstance() {
return LazyHolder.INSTANCE;
}
}