类 什么时候加载?
When classes are loaded?
嗯,我有这样一段代码:
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;
}
我不知道如何(全部或部分)以及何时加载 classes。所以:
Test t;
- 它不是一个活跃的用法,但引用 t
必须是一个明确的类型。测试 class 是否已加载(可能是部分加载,然后是多少个阶段 - loading\linking\initializing - 它通过了)还是什么都没发生?
Integer i = new Integer(1);
- 是在 JVM 启动时加载 Integer 还是在这一行?
t = new Test();
- 一个活跃的用法。它是从一开始就完全加载还是从某个点开始加载(见 1)
System.out.println(Test4.a);
- Test4
是否已加载?
- 是否加载了
Test2
和 Test3
?如果是那么什么时候?
当 classes 被加载时被 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.
(剪断)
A class or interface will not be initialized under any other circumstance.
Chapter 5 谈论加载、链接和初始化 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).
您的问题:
- 声明变量不会加载 class。但是加载发生在链接之前,而链接发生在初始化之前。因此,当加载 class 时,它也会被链接和初始化。
- 在您的代码运行之前,
Integer
class 由 JVM 加载(连同许多其他语言基础 classes)。
- 现在
Test
class 已加载,因为创建了一个新实例。
Test4
没有加载,因为只用了一个常量变量,与上面第4条规则冲突
Test3
和Test2
是在Test
加载之后加载的,因为Test2
对象是在Test
的实例初始化器中创建的,这也导致Test3
(超class)待加载。
这在running your code with the JVM option -verbose:class
时得到证实。
嗯,我有这样一段代码:
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;
}
我不知道如何(全部或部分)以及何时加载 classes。所以:
Test t;
- 它不是一个活跃的用法,但引用t
必须是一个明确的类型。测试 class 是否已加载(可能是部分加载,然后是多少个阶段 - loading\linking\initializing - 它通过了)还是什么都没发生?Integer i = new Integer(1);
- 是在 JVM 启动时加载 Integer 还是在这一行?t = new Test();
- 一个活跃的用法。它是从一开始就完全加载还是从某个点开始加载(见 1)System.out.println(Test4.a);
-Test4
是否已加载?- 是否加载了
Test2
和Test3
?如果是那么什么时候?
当 classes 被加载时被 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.
(剪断)
A class or interface will not be initialized under any other circumstance.
Chapter 5 谈论加载、链接和初始化 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).
您的问题:
- 声明变量不会加载 class。但是加载发生在链接之前,而链接发生在初始化之前。因此,当加载 class 时,它也会被链接和初始化。
- 在您的代码运行之前,
Integer
class 由 JVM 加载(连同许多其他语言基础 classes)。 - 现在
Test
class 已加载,因为创建了一个新实例。 Test4
没有加载,因为只用了一个常量变量,与上面第4条规则冲突Test3
和Test2
是在Test
加载之后加载的,因为Test2
对象是在Test
的实例初始化器中创建的,这也导致Test3
(超class)待加载。
这在running your code with the JVM option -verbose:class
时得到证实。