问题
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:
Test t;
- it is not an active usage, but the referencet
must be a definite type of. Was Test class loaded (maybe partially, then how many stages - loading\linking\initializing - it passed) or nothing happened?Integer i = new Integer(1);
- was Integer loaded when JVM starts or on this line?t = new Test();
- an active usage. Was it loaded fully from the beginning or from some point (see 1)System.out.println(Test4.a);
- wasTest4
loaded or not?- Were
Test2
andTest3
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:
- 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.
- The
Integer
class is loaded by the JVM (along with lots of other language foundation classes) before your code runs. - Now the
Test
class is loaded, because a new instance is created. Test4
was not loaded, because only a constant variable was used, which conflicts with the 4th rule above.Test3
andTest2
were loaded afterTest
was loaded, becauseTest2
objects were created inTest
's instance initializer, which also causedTest3
(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