java代码块执行顺序由jvm严格决定:静态块属类、加载时执行一次;构造块属对象、每次new时执行;普通块仅限作用域,不参与初始化。

Java代码块执行顺序不是靠猜,而是由JVM加载和实例化机制严格决定的。关键在于分清三类块的归属层级:静态块属于类,构造块(即实例块)属于对象,普通块只是作用域语法糖。
静态代码块:类加载时只跑一次
静态代码块(static {})在JVM首次主动使用该类时触发——比如new对象、调用静态方法、访问静态字段。它和静态变量初始化语句(如 public static int x = 10;)混写时,谁在源码里靠前,谁就先执行。多个静态块也按书写顺序依次运行。
- 不能访问实例成员(this、非static字段或方法)
- 适合做全局一次性操作:注册驱动、加载配置、初始化缓存
- 父类静态块一定早于子类静态块,哪怕子类被直接引用
- 若静态初始化中 new 了本类实例,会提前触发对象创建流程,可能引发未完全初始化的风险
构造代码块:每次new都走一遍
不带static的 {} 是构造代码块(也叫实例代码块),它不属于某个具体方法,但会在每个构造方法体开头、super()调用之后自动插入执行。它和实例变量显式赋值(如 String name = "Tom";)处于同一层级,按源码定义顺序交替执行。
- 可访问实例字段和方法,也能读取外部局部变量(若在方法内定义)
- 适合抽取多个构造器共用的初始化逻辑,避免重复代码
- 执行时机固定:父类构造块 → 父类构造方法 → 子类构造块 → 子类构造方法
- 即使写在构造方法后面,仍会在构造方法体之前运行
继承场景下的完整链条
当执行 new Child() 时,实际顺序是:
- Object类静态部分(通常不可见)
- 父类静态变量 → 父类静态块(按序)
- 子类静态变量 → 子类静态块(按序)
- 父类实例变量 → 父类构造块(按序) → 父类构造方法
- 子类实例变量 → 子类构造块(按序) → 子类构造方法
这个顺序确保父类状态总在子类之前就绪,也解释了为什么在构造块中调用被子类重写的方法,可能访问到尚未初始化的子类字段。
普通代码块:纯语法作用域
写在方法、构造器或语句内部的 { ... } 就是普通代码块,它不参与类或对象初始化流程,只控制变量作用域和逻辑分段。它的执行完全遵循代码从上到下的自然顺序,和类结构无关。
- 常见用途:限制临时变量生命周期、配合try-catch、组织可读性更强的逻辑段
- main里两个相邻的{},谁先写谁先执行
- 编译后不会生成额外字节码,仅影响局部作用域
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











