在Java中,类的执行顺序主要包括静态变量、静态代码块、实例变量、实例代码块、构造方法等的执行顺序
Java类的执行顺序
-
静态变量和静态代码块按顺序执行:在类加载时,静态变量和静态代码块按它们在类中出现的顺序依次执行。静态变量和静态代码块只在类第一次加载时执行一次。
-
实例变量和实例代码块按顺序执行:在创建对象时,实例变量和实例代码块按它们在类中出现的顺序依次执行。每次创建对象时,实例变量和实例代码块都会执行一次。
-
构造方法执行:实例变量和实例代码块执行完之后,才会执行构造方法。构造方法是在每次创建对象时执行的。
示例代码和执行顺序
简单示例
public class ExecutionOrder {
// 静态变量
static int staticVar = initStaticVar();
// 实例变量
int instanceVar = initInstanceVar();
// 静态代码块
static {
System.out.println("2. 静态代码块");
}
// 实例代码块
{
System.out.println("4. 实例代码块");
}
// 构造方法
public ExecutionOrder() {
System.out.println("5. 构造方法");
}
// 静态方法初始化静态变量
private static int initStaticVar() {
System.out.println("1. 静态变量初始化");
return 0;
}
// 实例方法初始化实例变量
private int initInstanceVar() {
System.out.println("3. 实例变量初始化");
return 0;
}
// 主方法
public static void main(String[] args) {
System.out.println("6. 创建对象1");
new ExecutionOrder();
System.out.println("\n6. 创建对象2");
new ExecutionOrder();
}
}
结果
1. 静态变量初始化
2. 静态代码块
6. 创建对象1
3. 实例变量初始化
4. 实例代码块
5. 构造方法6. 创建对象2
3. 实例变量初始化
4. 实例代码块
5. 构造方法
总结
-
静态变量和静态代码块在类加载时执行,只执行一次。
-
实例变量和实例代码块在每次创建对象时执行。
-
构造方法在实例代码块之后执行。
复杂示例
public class TestOrder {
// 静态变量
static int staticVar = initStaticVar();
// 静态代码块
static {
System.out.println("1. 静态代码块");
}
// 实例变量
int instanceVar = initInstanceVar();
int anotherInstanceVar;
// 实例代码块
{
System.out.println("4. 实例代码块");
anotherInstanceVar = 42; // 给另一个实例变量赋值
performSomeAction(); // 调用实例方法
}
// 构造方法
public TestOrder(int value) {
System.out.println("5. 构造方法开始");
// 在构造方法中增加静态代码块和实例代码块
static {
System.out.println("5.1 构造方法中的静态代码块");
}
{
System.out.println("5.2 构造方法中的实例代码块");
}
if (value > 10) {
this.instanceVar = value;
System.out.println("5.3 构造方法中:值大于10,instanceVar = " + value);
} else {
System.out.println("5.4 构造方法中:值小于等于10");
}
// 调用其他方法
anotherComplexMethod(value);
System.out.println("5. 构造方法结束");
}
// 静态方法初始化静态变量
private static int initStaticVar() {
System.out.println("2. 静态变量初始化");
return 0;
}
// 实例方法初始化实例变量
private int initInstanceVar() {
System.out.println("3. 实例变量初始化");
return 0;
}
// 实例方法
private void performSomeAction() {
System.out.println("4.1 实例代码块中调用的实例方法");
}
// 另一个实例方法
private void anotherComplexMethod(int value) {
System.out.println("5.5 构造方法中调用的另一个实例方法,value = " + value);
this.anotherInstanceVar += value;
System.out.println("5.6 构造方法中:anotherInstanceVar = " + anotherInstanceVar);
}
// 主方法
public static void main(String[] args) {
System.out.println("6. 创建对象1");
new TestOrder(5);
System.out.println("\n6. 创建对象2");
new TestOrder(15);
}
}
执行结果:
2. 静态变量初始化
1. 静态代码块
6. 创建对象1
3. 实例变量初始化
4. 实例代码块
4.1 实例代码块中调用的实例方法
5. 构造方法开始
5.2 构造方法中的实例代码块
5.4 构造方法中:值小于等于10
5.5 构造方法中调用的另一个实例方法,value = 5
5.6 构造方法中:anotherInstanceVar = 47
5. 构造方法结束6. 创建对象2
3. 实例变量初始化
4. 实例代码块
4.1 实例代码块中调用的实例方法
5. 构造方法开始
5.2 构造方法中的实例代码块
5.3 构造方法中:值大于10,instanceVar = 15
5.5 构造方法中调用的另一个实例方法,value = 15
5.6 构造方法中:anotherInstanceVar = 57
5. 构造方法结束
为什么5.1的构造方法中的静态代码块不输出?
执行顺序解析
-
类加载:静态变量和静态代码块按顺序执行,只在类加载时执行一次。
-
静态变量
staticVar
初始化并调用initStaticVar()
方法,输出 "2. 静态变量初始化"。 -
静态代码块执行,输出 "1. 静态代码块"。
-
-
主方法执行:静态初始化完成后,主方法开始执行,依次创建两个对象。
-
创建对象1:
-
实例变量
instanceVar
初始化并调用initInstanceVar()
方法,输出 "3. 实例变量初始化"。 -
实例代码块执行,输出 "4. 实例代码块" 和 "4.1 实例代码块中调用的实例方法"。
-
构造方法执行,输出 "5. 构造方法开始"、"5.2 构造方法中的实例代码块"、"5.4 构造方法中:值小于等于10"、"5.5 构造方法中调用的另一个实例方法,value = 5"、"5.6 构造方法中:anotherInstanceVar = 47" 和 "5. 构造方法结束"。
-
-
创建对象2:
-
实例变量
instanceVar
初始化并调用initInstanceVar()
方法,输出 "3. 实例变量初始化"。 -
实例代码块执行,输出 "4. 实例代码块" 和 "4.1 实例代码块中调用的实例方法"。
-
构造方法执行,输出 "5. 构造方法开始"、"5.2 构造方法中的实例代码块"、"5.3 构造方法中:值大于10,instanceVar = 15"、"5.5 构造方法中调用的另一个实例方法,value = 15"、"5.6 构造方法中:anotherInstanceVar = 57" 和 "5. 构造方法结束"。
-
总的来说,静态代码块在类加载时执行,实例代码块在每次创建对象时执行,构造方法在实例代码块之后执行。构造方法中不能包含静态代码块,实例代码块可以放在构造方法中,但它们的执行顺序仍然是按照类的初始化顺序进行。