实例化发生在getInstance()或getInstance()之前?

时间:2016-09-14 11:05:27

标签: java singleton

我按照本教程创建了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

我错了还是错了。请给我一些消息。

3 个答案:

答案 0 :(得分:2)

在这种特定代码的情况下,您可能正确。

但是,如果static的{​​{1}}方法,或EagerInitializedSingletonstatic成员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; 
  }
}