目录
1. 静态初始化(类加载阶段)
示例代码
输出
2. 实例初始化(对象创建阶段)
详细顺序
示例代码
输出
3. 关键规则总结
4. 注意事项
5. 完整流程图
在Java中,类的实例化过程(对象创建)遵循严格的执行顺序,包含静态初始化、实例变量初始化、构造代码块(实例代码块)以及构造方法的执行。以下是详细的分步说明:
1. 静态初始化(类加载阶段)
当一个类首次被加载到内存时,执行以下步骤(仅执行一次):
- 父类的静态变量初始化和静态代码块(如果存在继承关系)。
- 子类的静态变量初始化和静态代码块。
- 静态变量和静态代码块的执行顺序由它们在代码中的声明顺序决定。
示例代码
class Parent {
static {
System.out.println("父类静态代码块");
}
static String parentStaticVar = initParentStaticVar();
static String initParentStaticVar() {
System.out.println("父类静态变量初始化");
return "parent";
}
}
class Child extends Parent {
static String childStaticVar = initChildStaticVar();
static {
System.out.println("子类静态代码块");
}
static String initChildStaticVar() {
System.out.println("子类静态变量初始化");
return "child";
}
}
输出
父类静态代码块
父类静态变量初始化
子类静态变量初始化
子类静态代码块
2. 实例初始化(对象创建阶段)
每次通过new关键字创建对象时,执行以下步骤:
- 父类的实例变量初始化和实例代码块(如果存在继承关系)。
- 父类的构造方法。
- 子类的实例变量初始化和实例代码块。
- 子类的构造方法。
详细顺序
- 父类实例变量初始化和实例代码块:
- 按照代码中的声明顺序执行。
- 父类构造方法:
- 默认调用父类无参构造方法(如果没有显式调用其他构造方法)。
- 子类实例变量初始化和实例代码块:
- 按照代码中的声明顺序执行。
- 子类构造方法。
示例代码
class Parent {
String parentVar = initParentVar();
{
System.out.println("父类实例代码块");
}
Parent() {
System.out.println("父类构造方法");
}
String initParentVar() {
System.out.println("父类实例变量初始化");
return "parent";
}
}
class Child extends Parent {
String childVar = initChildVar();
{
System.out.println("子类实例代码块");
}
Child() {
System.out.println("子类构造方法");
}
String initChildVar() {
System.out.println("子类实例变量初始化");
return "child";
}
}
public class Main {
public static void main(String[] args) {
new Child();
}
}
输出
父类实例变量初始化
父类实例代码块
父类构造方法
子类实例变量初始化
子类实例代码块
子类构造方法
3. 关键规则总结
- 静态优先于实例:
- 静态变量和静态代码块在类加载时执行,且仅执行一次。
- 父类优先于子类:
- 无论是静态初始化还是实例初始化,父类先于子类执行。
- 声明顺序决定执行顺序:
- 静态变量/代码块、实例变量/代码块的执行顺序由它们在代码中的位置决定。
- 构造方法最后执行:
- 构造方法中的代码在实例变量和实例代码块之后执行。
4. 注意事项
-
避免在构造方法中调用可被覆盖的方法:
- 如果父类构造方法调用了子类重写的方法,此时子类实例变量可能尚未初始化,导致意外行为。
class Parent { Parent() { print(); // 危险:子类重写的方法可能访问未初始化的变量 } void print() { System.out.println("Parent"); } } class Child extends Parent { int value = 10; @Override void print() { System.out.println("Child.value = " + value); // 输出0(未初始化) } } -
静态变量依赖:
- 静态变量的初始化顺序可能导致依赖问题(如循环依赖)。
5. 完整流程图
类加载阶段:
父类静态变量/代码块 → 子类静态变量/代码块
对象实例化阶段:
父类实例变量/代码块 → 父类构造方法 → 子类实例变量/代码块 → 子类构造方法
通过理解这些规则,可以避免因初始化顺序导致的逻辑错误,例如变量未初始化、空指针等问题。
这篇博客到这里就接近尾声了,希望我的分享能给您带来一些启发和帮助,别忘了点赞、收藏。您的每一次互动、鼓励是我持续创作的动力!期待与您再次相遇,共同探索更广阔的世界!



















