When classes are loaded?

人走茶凉 提交于 2021-02-18 22:25:48

问题


Well, I've got such a code:

public class Main {
    public static void main(String[] args) {
        Test t; //1
        Integer i = new Integer(1); //2
        t = new Test(); //3
        System.out.println(Test4.a); //4
    }
}

class Test {
    private int a = 10;
    private Test2 t2; //5

    List<Test2> list = new ArrayList<Test2>() {
        {
            for (int i = 0; i < a; i++) {
                add(new Test2()); //6
            }
        }
    };
}

class Test2 extends Test3{
}

class Test3 {
}

class Test4 {
    public static final int a = 4;
}

I don't know how (fully or partially) and when classes are loaded. So:

  1. Test t; - it is not an active usage, but the reference t must be a definite type of. Was Test class loaded (maybe partially, then how many stages - loading\linking\initializing - it passed) or nothing happened?
  2. Integer i = new Integer(1); - was Integer loaded when JVM starts or on this line?
  3. t = new Test(); - an active usage. Was it loaded fully from the beginning or from some point (see 1)
  4. System.out.println(Test4.a); - was Test4 loaded or not?
  5. Were Test2 and Test3 loaded or not? If yes then when?

回答1:


When classes are loaded is covered by the JLS, Section 12.4.1.

A class or interface type T will be initialized immediately before the first occurrence of any one of the following:

  • T is a class and an instance of T is created.

  • T is a class and a static method declared by T is invoked.

  • A static field declared by T is assigned.

  • A static field declared by T is used and the field is not a constant variable (§4.12.4).

  • T is a top level class (§7.6), and an assert statement (§14.10) lexically nested within T (§8.1.3) is executed.

(snip)

A class or interface will not be initialized under any other circumstance.

Chapter 5 talks about loading, linking, and initializing classes.

The Java Virtual Machine dynamically loads, links and initializes classes and interfaces. Loading is the process of finding the binary representation of a class or interface type with a particular name and creating a class or interface from that binary representation. Linking is the process of taking a class or interface and combining it into the run-time state of the Java Virtual Machine so that it can be executed. Initialization of a class or interface consists of executing the class or interface initialization method (§2.9).

Your questions:

  1. Declaring a variable doesn't load the class. But loading happens before linking, and linking happens before initialization. So, when a class is loaded, it is also then linked and initialized.
  2. The Integer class is loaded by the JVM (along with lots of other language foundation classes) before your code runs.
  3. Now the Test class is loaded, because a new instance is created.
  4. Test4 was not loaded, because only a constant variable was used, which conflicts with the 4th rule above.
  5. Test3 and Test2 were loaded after Test was loaded, because Test2 objects were created in Test's instance initializer, which also caused Test3 (the superclass) to be loaded.

This is confirmed when running your code with the JVM option -verbose:class.



来源:https://stackoverflow.com/questions/33244715/when-classes-are-loaded

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!