【JAVA】类加载在什么时候发生
【JAVA】类加载在什么时候发生
Sarzn类加载
每个类的类加载有且只发生一次
类加载: 就是 JVM 把 .class 文件读到内存里,并完成静态字段(成员变量)初始化和静态代码块执行,让这个类准备好被使用
有一下几种情况会触发类加载
- new一个新对象
- 调用类的静态成员变量(静态字段)或静态代码块
- 子类被调用要先加载父类
懒加载: 如果在程序一开始运行的时候就把所有的类都全部加载一遍, 这太耗费资源了, JVM 对于类加载是能拖就拖, 直到出现了上述的情况让他不得不进行类加载
加载顺序
加载的顺序如下表所示
| 步骤 | 内容 | 时机 |
|---|---|---|
| 1 | 父类静态字段 + 父类静态代码块 | 类加载时,只执行一次 |
| 2 | 子类静态字段 + 子类静态代码块 | 类加载时,只执行一次 |
| 3 | 父类实例字段 + 父类实例代码块 | 每次 new 对象时 |
| 4 | 父类构造方法 | 每次 new 对象时 |
| 5 | 子类实例字段 + 子类实例代码块 | 每次 new 对象时 |
| 6 | 子类构造方法 | 每次 new 对象时 |
举个例子 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84class Parent {
// ===== 静态部分(类加载时执行,全程序只一次)=====
static int parentStatic = print("1. Parent 静态字段", 100);
static {
System.out.println("2. Parent 静态代码块");
}
// ===== 实例部分(每次 new 时执行)=====
int parentField = print("4. Parent 实例字段", 10);
{
System.out.println("5. Parent 实例代码块");
}
public Parent() {
System.out.println("6. Parent 构造方法");
}
// ===== 方法(被调用时才执行)=====
public void hi() {
System.out.println(">> Parent.hi() 被调用");
}
public static void hello() {
System.out.println(">> Parent.hello() 静态方法被调用");
}
static int print(String msg, int val) {
System.out.println(msg + " = " + val);
return val;
}
}
class Child extends Parent {
static int childStatic = print("3. Child 静态字段", 200);
static {
System.out.println("3.5 Child 静态代码块");
}
int childField = print("7. Child 实例字段", 20);
{
System.out.println("8. Child 实例代码块");
}
public Child() {
System.out.println("9. Child 构造方法");
}
public void hi() {
System.out.println(">> Child.hi() 被调用(重写)");
}
}
class Unused {
static {
System.out.println("!!! Unused 被加载了 !!!");
}
}
public class Main {
public static void main(String[] args) {
System.out.println("==== 程序开始 ====\n");
System.out.println("---- 步骤 1:第一次 new Child() ----");
Child c1 = new Child();
System.out.println("\n---- 步骤 2:第二次 new Child() ----");
Child c2 = new Child();
System.out.println("\n---- 步骤 3:调用实例方法(多态)----");
Parent p = c1;
p.hi();
System.out.println("\n---- 步骤 4:调用静态方法 ----");
Parent.hello();
System.out.println("\n==== 程序结束 ====");
System.out.println("(Unused 类自始至终没被加载)");
}
}
1 | ==== 程序开始 ==== |
总结: JVM 在最晚的时机(第一次用到)加载这个类,加载之后再也不重复。



