普通代码块是写在类中、方法外的{...},仅在new对象时、构造方法执行前自动运行一次。它属于实例级别,每次new都执行一次,与方法调用无关,也不参与后续任何操作。

普通代码块的生命周期只绑定对象创建,不随方法调用而触发。它在每次 new 对象时、构造方法执行前 自动运行一次,之后就彻底退出生命周期——无论你后续调用多少次方法,甚至完全不调用任何方法,它都不会再出现。
普通代码块在哪?什么时候执行?
普通代码块是写在类中、方法外的一对大括号 { ... },属于实例级别。它的执行时机非常明确:
- 仅在 new 实例时触发,且严格位于构造方法体开始执行之前
- 每 new 一个对象,就执行一次;new 十次,执行十次
- 类加载、静态代码块执行、main 方法启动等过程,都和它无关
- 哪怕该对象后续只调用静态方法或根本不调用任何方法,普通代码块早已执行完毕
它和方法里的 {} 完全不是一回事
方法内部写的 { System.out.println("hi"); } 是局部代码块,作用只是限制变量作用域或组织逻辑,不属于初始化流程:
- 它不参与对象构建,也不受 new 影响
- 只有当程序执行流真正走到这个位置时,它才运行
- 它不能访问尚未声明的变量,也不能依赖未初始化的实例字段(编译器会阻止)
- JVM 不把它看作“代码块初始化机制”的一部分
为什么容易混淆?关键在“位置”和“阶段”
混淆常源于没分清两个独立阶段:
立即学习“Java免费学习笔记(深入)”;
- 对象初始化阶段:包含静态代码块(类加载时)、普通代码块(new 时)、构造方法(new 时)
- 方法调用阶段:发生在对象已存在之后,由显式调用驱动,与初始化流程无交集
- 普通代码块只存在于第一阶段,且仅一次;方法调用可反复发生,但不会唤醒它
一个典型验证示例
下面这段代码能清晰体现生命周期边界:
class Demo {
{ System.out.println("普通代码块执行"); } // 普通代码块
public Demo() { System.out.println("构造方法执行"); }
public void doWork() {
{ System.out.println("方法内局部块"); } // 局部块,和上面那个无关
}
}
// 调用:
Demo d = new Demo(); // 输出两行:“普通代码块执行”、“构造方法执行”
d.doWork(); // 输出一行:“方法内局部块”
注意:第二行输出证明普通代码块已完成使命;第三行输出属于另一个执行上下文,两者时间、语义、生命周期均无关联。


















