静态代码块、构造代码块、构造方法的执行顺序是什么?

本文详细解析了Java中类的加载与初始化过程,通过一个具体的示例代码演示了类加载时静态代码块与实例化时构造方法的执行顺序。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

package com;
class BaseTmp {
BaseTmp() {System.out.println(“BaseTmp instance.” );}
}

class Base {BaseTmp tmp = new BaseTmp();
static { System.out. println( “Base static{}.” );
}
Base() { System.out.println(“Base instance.”);
}
}

class BaseChild extends Base {

BaseTmp tmp=new BaseTmp();
static { System. out.println( "BaseChild static{}." );
}
BaseChild() { System. out.println("BaseChild instance.");
}

}

public class Test1 {
public static void main( String argv []) {
new BaseChild ();
}
}


运行结果如下
Base static{}.

BaseChild static{}.

BaseTmp instance.

Base instance.

BaseTmp instance.

BaseChild instance.

首先程序加载了 Demo 类进来,接着执行 Demo 类中程序的入口 main 方法,在 main 方法中我们创建了 BaseChild 实例,而第一次创建 BaseChild 实例前需要先把 BaseChild 类加载进来,而 BaseChild 又继承自 Base 类,所以要加载 BaseChild 得先加载 Base 类,在加载 Base 类时由于 Base 类中有一个静态代码块,所以会先执行打印 Base static{}.,接着加载了 BaseChild 类执行了其中的静态代码块打印为 BaseChild static{}.,当类加载完成以后就开始实例化阶段了,实例化 BaseChild 对象之前得先实例化 Base 对象(因为子类构造方法会调用父类构造方法,所以得先实例化父类),实例化 Base 对象前还得先初始化(即获取类的属性并初始化),所以 Base 类中 BaseTmp 属性先被实例化,所以打印 BaseTmp instance.,接着执行 Base 类的构造方法打印 Base instance.,然后回退到子类也是先初始化然后实例化,同理打印 BaseTmp instance. 和 BaseChild instance

### Java 中静态方法、静态代码块构造方法执行顺序 在 Java 中,程序运行时类加载的过程决定了静态方法、静态代码块以及构造方法执行顺序。以下是详细的分析: #### 类加载过程中的执行顺序 当一个类被加载到 JVM 中时,其初始化阶段会按以下顺序执行: 1. **静态代码块**:静态代码块会在类加载时被执行一次,并且按照它们在源码中定义的顺序依次执行[^2]。 2. **静态变量赋值**:如果存在静态成员变量(如 `static` 字段),这些字段会被初始化并分配默认值或显式指定的初始值[^3]。 3. **静态方法调用**:静态方法可以在类加载完成后通过类名直接调用,或者由其他地方触发调用。 只有当创建对象实例时才会涉及构造方法及其相关部分: 4. **构造代码块**:每次创建新对象时都会执行构造代码块,它位于构造方法之前[^1]。 5. **构造方法**:最后执行的是与当前对象关联的具体构造方法[^1]。 因此,在整个生命周期来看,完整的执行流程可以总结如下: - 静态代码块 → (可能存在的) 静态方法调用 → 构造代码块构造方法。 需要注意的一点是,尽管静态方法可以通过对象来访问,但实际上它是属于类级别的操作;也就是说即使没有实际的对象存在也能正常工作[^2]。 下面给出一段示例代码展示这种行为模式: ```java public class ExecutionOrderExample { static { System.out.println("Static block executed"); } { System.out.println("Instance initialization block executed"); } public ExecutionOrderExample(){ System.out.println("Constructor called"); } public static void main(String[] args){ System.out.println("Before object creation"); // 创建第一个对象前后的打印语句用于区分不同时间点的行为 new ExecutionOrderExample(); System.out.println("\nCalling a static method now:"); callStaticMethod(); // 再次创建另一个对象观察重复情况下的表现差异 new ExecutionOrderExample(); } public static void callStaticMethod(){ System.out.println("Inside the static method."); } } ``` 此代码片段展示了从启动应用程序直到完成两个独立对象构建期间各个组件是如何交互工作的。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值