普通代码块在new对象时、构造方法前自动执行一次,与方法调用无关;方法内{}是局部块,仅在方法执行时按序运行。

普通代码块(即实例代码块)和方法的执行顺序,关键在于区分“对象初始化阶段”和“方法调用阶段”。前者在 new 对象时自动触发,后者需 显式调用才运行,二者不混在同一流程里。
普通代码块只参与对象创建,不参与方法调用
普通代码块({ ... })写在类中、方法外,属于实例级别。它会在每次 new 对象时、构造方法体执行前自动运行,且仅此一次——和你是否调用某个方法完全无关。
- 即使类里定义了十个方法,只要没 new 对象,普通代码块一概不执行
- 哪怕你 new 完对象后,全程只调用静态方法或什么也不调,普通代码块也早已执行完毕
- 它不会因为你在方法里又写了个
{}就被误认为是“普通代码块”——方法内部的{}是局部作用域块,不属于初始化流程
方法内普通块(局部代码块)完全独立于初始化流程
写在方法里的 { System.out.println("hello"); },只是限制变量生命周期或提升可读性的语法结构,JVM 不把它视作“代码块初始化机制”的一部分。
- 它在方法执行到该位置时才运行,时机由方法调用栈决定
- 它不能访问未声明的变量,也不能提前使用尚未初始化的实例字段(编译器会报错)
- 例如:
void test() { int x = 1; { int y = x + 1; System.out.println(y); } System.out.println(x); }—— y 的作用域仅限于内层{},但不影响外层逻辑
实战中如何验证执行先后?看三步输出节奏
用一个带静态块、实例块、构造方法和普通方法的类,按以下顺序观察输出:
- 首次
new A():先输出静态块(类加载),再实例块 → 构造方法 → 完成对象创建 - 再次
new A():跳过静态块,直接实例块 → 构造方法 - 之后调用
a.doWork():此时才执行方法体,其中的任何局部{}块,都在方法执行流中按顺序运行
你会发现:所有“初始化相关”的输出(静态块、实例块、构造方法)集中在对象诞生那一刻;而方法相关输出,永远出现在你主动触发调用之后。
常见误用与规避建议
新手容易把“想复用的初始化逻辑”错误塞进方法里,导致每次调用都重复执行;或把本该放实例块的共用初始化,拆到每个构造方法中。
- ✅ 正确做法:多个构造方法都要赋值
id和createTime?统一提到实例代码块里 - ❌ 错误做法:在
init()方法里做同样事,然后每个构造方法末尾手动调用——既破坏封装,又易遗漏 - ⚠️ 注意边界:实例块不能访问
this以外的未初始化实例字段(如字段声明在实例块之后),编译会拒绝
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











