有或没有 holder 的单身人士 = 懒惰与急切的初始化?

Singleton with or without holder = lazy vs eager initialisation?

这是否正确:

有持有人的单身人士。

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

没有持有人的单身人士。

public class Singleton{
   private static final Singleton INSTANCE = new Singleton();
   public static Singleton getInstance(){
      return INSTANCE;
   }
   private Singleton(){ }
}

Update 回应@jan 的建议,即这是 What is an efficient way to implement a singleton pattern in Java?. I disagree. I am not asking what is the best way to do it: I am only asking what makes these two specific implementations lazy vs eager loading. Answers like xyz's 的重复,广泛地解决懒惰与急切的问题,但不是通过对比我尝试的两个例子检查(或使用相同的关键字,这就是为什么它从未出现在我的初始搜索中)。

作为对@Sriram 的回应,这是我的测试来证明哪个是急切加载还是延迟加载。

使用 holder 延迟加载

public class Singleton {
   private static class SingletonHolder {
      static {
         System.out.println("In SingletonHolder static block.");
      }
      private static final Singleton INSTANCE = new Singleton();
   }

   public static Singleton getInstance() {
      System.out.println("In getInstance().");
      return SingletonHolder.INSTANCE;
   }

   private Singleton() {
      System.out.println("In constructor.");
   }

   private void doSomething() {
      System.out.println("Singleton working.");
   }

   public static void main(String[] args) {
      System.out.println("Start of main.");
      Singleton.getInstance().doSomething();
      System.out.println("End of main.");
   }
}

输出显示 main 方法在调用 getInstance() 之前启动,因此延迟加载。

Start of main.
In getInstance().
In SingletonHolder static block.
In constructor.
Singleton working.
End of main.

没有支架的预加载

public class Singleton {

   static {
      System.out.println("In Singleton static block.");
   }

   private static final Singleton INSTANCE = new Singleton();

   public static Singleton getInstance() {
      System.out.println("In getInstance().");
      return INSTANCE;
   }

   private Singleton() {
      System.out.println("In constructor.");
   }

   private void doSomething() {
      System.out.println("Singleton working.");
   }

   public static void main(String[] args) {
      System.out.println("Start of main.");
      Singleton.getInstance().doSomething();
      System.out.println("End of main.");
   }

}

输出显示 main 方法在 调用 getInstance() 方法后启动 ,因此被急切加载。

In Singleton static block.
In constructor.
Start of main.
In getInstance().
Singleton working.
End of main.