静态代码块先于构造代码块执行:静态块属类、类加载时仅执行一次;构造块属对象、每次new时在super()后、构造方法前执行。

静态代码块和构造代码块的执行顺序不是凭经验猜的,而是由 JVM 类加载与对象实例化机制严格决定的。关键要抓住两点:静态代码块属于类,只在类加载时执行一次;构造代码块属于对象,每次 new 时都执行,且总在构造方法体之前运行。
静态代码块:类加载时执行一次
它在 JVM 第一次主动使用该类时触发,比如 new 对象、调用静态方法、访问静态字段,或通过 Class.forName 加载。多个静态块按源码书写顺序依次执行。它不能访问 this、非 static 字段或方法,适合做一次性初始化,例如:
- 注册 JDBC 驱动
- 加载配置文件到静态缓存
- 初始化全局常量或共享资源池
注意:父类静态块一定先于子类静态块执行,哪怕你直接 new 子类——JVM 会先确保父类已加载完毕。
构造代码块:每次 new 都执行,且在构造方法前
它没有 static 修饰,写在类中、方法外。编译后会被“插入”到每个构造方法的第一行(super() 或 this() 调用之后)。它可访问实例字段、方法,也能读取外部局部变量(若定义在方法内)。典型用途是抽取多个构造器共用的初始化逻辑,避免重复代码。例如:
立即学习“Java免费学习笔记(深入)”;
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 统一设置默认状态(如 status = "INIT")
- 初始化集合字段(如 list = new ArrayList<>())
- 记录对象创建日志
在继承场景中,执行顺序固定为:父类构造块 → 父类构造方法 → 子类构造块 → 子类构造方法。
完整执行链条(以 new Child() 为例)
整个流程体现“先类后对象、先父后子”的原则:
- Object 类静态部分(通常不可见)
- 父类静态变量初始化 → 父类静态代码块(按序)
- 子类静态变量初始化 → 子类静态代码块(按序)
- 父类实例变量初始化 → 父类构造代码块(按序) → 父类构造方法
- 子类实例变量初始化 → 子类构造代码块(按序) → 子类构造方法
这个顺序保证了父类状态始终在子类之前就绪,也解释了为什么在构造块里调用被重写的方法,可能访问到尚未初始化的子类字段。
普通代码块:不参与初始化,只管作用域
写在方法内部、构造器内或语句中的 { } 就是普通代码块。它不参与类或对象生命周期,纯粹控制变量可见范围和逻辑分段。比如限制临时变量生命周期、配合 try-catch 分组,或提升可读性。它按代码自然顺序执行,编译后不会生成额外字节码。

















