静态代码块在多层继承中严格按继承层级自顶向下执行且仅一次,起点为最上层父类而非object;首次主动使用任一子类时触发整条链的静态初始化,同一类中多个静态块按源码书写顺序执行。

静态代码块在多层继承中严格按类的继承层级自顶向下执行,且每个类只执行一次。
执行起点是顶层父类,不是 Object
虽然继承链最终到 java.lang.Object,但它没有用户定义的静态内容,所以实际起点是你自己写的最上层父类。JVM 在首次主动使用任一子类(比如 new Son() 或调用 Son.staticMethod())时,会向上追溯并确保所有祖先类完成静态初始化。
- 先加载并初始化 GrandFather 类:按源码顺序执行其静态变量赋值 → 静态代码块
- 再初始化 Father 类:同样顺序执行静态变量 → 静态代码块
- 最后初始化 Son 类:执行其静态变量 → 静态代码块
只触发一次,与对象数量无关
静态代码块属于类级别初始化,不是对象级别。只要某个类被 JVM 首次主动使用,它的静态部分就跑完,之后无论创建多少个该类或其子类的对象,都不会重复执行。
- 哪怕先 new Father(),再 new Son(),GrandFather 和 Father 的静态块已在第一次触发时完成,Son 的静态块在它首次被使用时补上
- 调用 Father.staticField 不会触发 Son 初始化;但调用 Son.staticField 一定会连带触发 GrandFather 和 Father 的静态初始化
同一类中多个静态块按书写顺序执行
如果一个类里写了三个 static{} 块,它们会从上到下依次运行,中间穿插静态变量赋值语句——谁写在前面,谁先执行。
- 例如:static int a = initA(); 写在第一个 static 块前,那 initA() 就最先调用
- 静态块内不能访问非静态成员,也不能用 this,但适合做日志配置、单例初始化、常量预加载等全局准备动作
main 类位置会影响观察结果
如果 main 方法写在子类里,JVM 启动时就会加载这个子类,从而提前触发整个继承链的静态初始化。这容易让人误以为“子类先执行”,其实是 JVM 强制保障“父类必须先完成”的体现。
- 为清晰区分加载时机和实例化时机,建议把测试 main 放在独立工具类中
- 加带标签的日志(如 [S] GrandFather)能直观验证顺序是否符合预期
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











