构造代码块在每次创建对象时执行,且一定在构造方法体之前、父类构造方法调用完成之后运行;它是编译器自动插入每个构造方法开头的实例初始化环节,按源码顺序执行,用于统一初始化所有对象共有的状态。

Java构造代码块(即实例代码块)在每次创建对象时执行,且一定在构造方法体之前、父类构造方法调用完成之后运行。它不是可选的“补充逻辑”,而是编译器自动插入到每个构造方法开头的关键初始化环节——理解这一点,才能真正把对象初始化管清楚。
构造代码块的本质与定位
构造代码块是用 { } 直接写在类体中、方法外的代码段,不加 static。它不属于某个具体构造方法,但会“复制”进每一个构造方法的最前面(编译期处理)。这意味着:
- 只要 new 一个对象,不管调用哪个构造方法,该块都会执行一次
- 它比构造方法体更早拿到对象引用(this 已可用),但此时父类构造已结束、本类字段已声明(含默认初始化)
- 多个构造代码块按源码顺序依次执行,就像语句一样逐行跑
- 不能访问尚未声明的字段(会出现“非法前向引用”编译错误)
和静态块、构造方法的协作关系
三者不是并列选项,而是分阶段、有依赖的初始化链条:
- 静态代码块:类加载时执行一次,负责类级别准备(如 static 变量赋值、驱动注册),不涉及任何对象
- 构造代码块:每次 new 对象时执行,在父类构造返回后、本类构造体开始前,负责所有对象共有的初始化动作(如统一设置 ID、日志标记、资源预分配)
- 构造方法:在构造代码块之后执行,负责差异化初始化(如根据参数设置 name/age、校验输入、启动线程等)
例如:一个 Student 类用构造代码块生成学号(S1001、S1002…),而构造方法决定是本科生还是研究生——前者统一,后者定制。
在继承场景下的完整顺序
当存在父子类时,初始化严格按“静态→实例→构造”+“父→子”双维度展开:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 父类静态变量 → 父类静态代码块
- 子类静态变量 → 子类静态代码块
- 父类普通变量 → 父类构造代码块
- 父类构造方法
- 子类普通变量 → 子类构造代码块
- 子类构造方法
注意:子类构造方法第一行默认是 super(),这触发了父类实例部分的执行;而构造代码块就插在这条 super() 调用返回之后、构造方法大括号内的代码开始之前。
实用建议:什么该放,什么不该放
构造代码块适合放所有构造路径都必须做的、与参数无关的初始化。比如:
- 给 final 字段赋非编译时常量的初始值(如 new Date())
- 初始化集合字段:list = new ArrayList();
- 记录创建时间、分配唯一序列号、打调试日志
避免放入:
- 耗时操作(如 I/O、网络请求)——会影响所有构造路径,且无法被重载绕过
- 依赖构造参数的逻辑(应交给构造方法)
- 可能抛出受检异常的代码(构造代码块不能声明 throws,只能 try-catch)
不复杂但容易忽略:它和字段声明顺序有关。字段声明和构造代码块交替出现时,JVM 按文本顺序依次执行初始化——先声明的字段先默认初始化,再遇到代码块就执行,再声明下一个字段……这个细节常导致“变量未初始化”的错觉。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










