一个Case

  1. public class Singleton {
  2. private Singleton() {
  3. }
  4. private static class LazyHolder {
  5. static final Singleton INSTANCE = new Singleton();
  6. static final int i = 10;
  7. static {
  8. System.out.println("LazyHolder.");
  9. System.out.println(i);
  10. }
  11. }
  12. public static Object getInstance(boolean flag) {
  13. if (flag) return new LazyHolder[2];
  14. return LazyHolder.INSTANCE;
  15. }
  16. public static void main(String[] args) {
  17. getInstance(true);
  18. System.out.println("----");
  19. getInstance(false);
  20. }
  21. }

问题 1:新建数组(第 16行)会导致 LazyHolder 的加载吗?会导致它的初始化吗?不会
问题 2:新建数组会导致 LazyHolder 的链接吗? 不会

解读:

  1. 新建数组会加载元素类LazyHolder;不会初始化元素类
  2. 新建数组不会链接元素类LazyHolder;在getInstance(false)时才真正链接和初始化
    1.虚拟机必须知道(加载)有这个类,才能创建这个类的数组(容器),但是这个类并没有被使用到(没有达到初始化的条件),所以不会初始化。

2.新建数组的时候并不是要使用这个类(只是定义了放这个类的容器),所以不会被链接,调用getInstance(false)的时候约等于告诉虚拟机,我要使用这个类了,你把这个类造好(链接),然后把static修饰的字符赋予变量(初始化)。

概要

JVM如何加载Class.png