有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java实例化发生在getInstance()之前还是getInstance()时?

下面是创建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;
    }
}

If your singleton class is not using a lot of resources, this is the approach to use. But in most of the scenarios, Singleton classes are created for resources such as File System, Database connections etc and we should avoid the instantiation until unless client calls the getInstance method.

问题是:

他们说,除非客户机调用getInstance方法,否则我们应该避免实例化 但正如我在这段代码中所知道的,(对象实例的)实例化总是在类EagerInitializedSingleton加载时发生,并且EagerInitializedSingleton仅在我们调用EagerInitializedSingleton.getInstance()
时加载 =>;实例化将与getInstance()一起准时发生,而不会在getInstance()之前发生

参考:

静态变量只在执行开始时初始化一次(当类加载器第一次加载类时)。 (来自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

我错了还是对了。请给我一些建议


共 (1) 个答案

  1. # 1 楼答案

    They say we should avoid the instantiation until unless client calls the getInstance method

    解决方案是延迟加载。 从wikipedia, Initialization-on-demand holder idiom

    When the class Something is loaded by the JVM, the class goes through initialization. Since the class does not have any static variables to initialize, the initialization completes trivially. The static class definition LazyHolder within it is not initialized until the JVM determines that LazyHolder must be executed. The static class LazyHolder is only executed when the static method getInstance is invoked on the class Something, and the first time this happens the JVM will load and initialize the LazyHolder class.

    public class Something {
      private Something() {}
    
      private static class LazyHolder {
        private static final Something INSTANCE = new Something();
      }
    
      public static Something getInstance() {
        return LazyHolder.INSTANCE; 
      }
    }