最新下载
热门教程
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
Java类成员初始化:静态代码块和声明处赋值的顺序
时间:2026-06-25 08:25:52 编辑:袖梨 来源:一聚教程网
静态代码块和声明处赋值按源码顺序执行,合并入<clinit>方法;父类先于子类初始化;异常导致类初始化失败并抛NoClassDefFoundError。
静态代码块和声明处赋值都属于类初始化阶段,它们的执行顺序严格按源码中出现的先后位置决定——谁写在上面,谁就先执行。
静态成员按源码顺序逐行执行
Java 把所有静态变量显式初始化(如 static int x = getValue();)和静态代码块(static { ... })合并进同一个 <clinit> 方法,JVM 按文件从上到下扫描并依次插入指令:
- 如果静态变量声明在前,它的初始化表达式会先执行;
- 如果静态块写在变量声明之前,块内不能引用该变量(编译报错:非法前向引用);
- 变量即使只声明未赋值(如
static int y;),也在“准备阶段”被设为默认值(0 / null / false),但显式初始化动作仍按代码位置触发。
声明可见性 ≠ 执行时机
字段名在整个类体中都处于作用域内,所以静态块里可以提前给尚未声明的静态字段赋值(编译通过),但最终值由执行顺序决定:
- 静态字段先被赋予默认值(如 int → 0);
- 然后按源码顺序执行静态块和声明处赋值;
- 后执行的语句会覆盖前面的赋值结果。
例如:static { a = 2; } 写在 static int a = 1; 前,a 最终是 1,不是 2。
立即学习“Java免费学习笔记(深入)”;
父子类之间强制分层执行
子类首次被主动使用时,JVM 保证父类静态部分全部完成后再执行子类静态部分:
- 先执行父类中所有静态变量赋值 + 静态块(按父类源码顺序);
- 再执行子类中所有静态变量赋值 + 静态块(按子类源码顺序);
- 因此子类静态块可安全读取父类 public static 字段,但父类不能依赖子类静态变量。
异常会中断整个初始化流程
静态变量初始化或静态块中抛出未捕获异常(如 NullPointerException),会导致:
-
<clinit>执行立即终止; - 该类进入“初始化失败”状态;
- 后续任何访问(调用方法、new 实例、读字段)都会直接抛
NoClassDefFoundError; - 不会重试,也不会执行其后未执行的静态代码。
相关文章
- 无限暖暖2.1版本下半奇迹之冠巅峰赛通关指南 06-27
- 逆战未来收藏室解锁攻略 06-27
- 逆战未来武器强度榜分析一览 06-27
- 心动小镇园艺怎么快速升级 06-27
- 息风谷战略邪线结局攻略 06-27
- 心动小镇水豚吃什么食物 06-27