java类初始化顺序严格遵循“静态优先、父类先行、书写顺序”规则:先父类静态变量与静态块(仅首次主动使用时执行),再子类静态部分;接着父类实例变量、构造块、构造函数,最后子类实例部分。

Java类的初始化顺序不是靠经验猜测,而是有严格规则可循。掌握它,能避免空指针、字段未初始化、父类依赖子类状态等隐蔽问题。关键不在“写多少”,而在“写在哪”和“谁先谁后”。
静态部分:只执行一次,且必须最先完成
静态变量赋值与静态代码块按源码顺序依次执行,整个过程在类首次被主动使用(如 new、调用静态方法、访问静态字段)时触发,且仅一次。
- 把全局配置、单例实例、常量计算等一次性初始化逻辑放在这里
- 避免在静态块中调用可能依赖未初始化子类的方法(如重写的虚方法),否则可能读到默认值(如 0 或 null)
- 多个静态块之间若存在依赖,务必按赋值先后排列——JVM不保证跨类静态初始化顺序,但保证本类内按书写顺序
实例部分:每次 new 都走一遍,顺序固定
创建对象时,实例变量显式赋值与构造代码块(即非静态初始化块)混合执行,顺序与它们在类中出现的位置一致,都在构造函数体之前。
- 构造代码块适合封装多个构造器共用的初始化逻辑(比如日志记录、资源预检查)
- 实例变量直接赋值(如 String name = "default";)和构造代码块本质等价,选其一即可,避免重复或冲突
- 不要在构造代码块里调用可能被子类重写的方法——此时子类字段尚未赋值,容易引发异常或错误结果
继承场景下:父类先行,逐层向下
有父子关系时,初始化链条不可跳过,完整顺序是:
- 父类静态变量 → 父类静态代码块
- 子类静态变量 → 子类静态代码块
- 父类实例变量 → 父类构造代码块 → 父类构造函数
- 子类实例变量 → 子类构造代码块 → 子类构造函数
这意味着:父类构造函数执行时,子类的任何实例字段都还是默认值(int 是 0,引用是 null)。如果父类构造器中调用了被子类重写的方法,而该方法又访问了子类字段,就会得到未初始化的状态。
实用建议:让初始化意图清晰可见
- 静态初始化集中放在类顶部,用注释标明用途(如 // 初始化数据库连接池)
- 避免在静态块或构造代码块中做耗时操作(如网络请求、大文件读取),影响类加载或对象创建性能
- 优先使用 final 字段 + 构造函数参数注入,而非依赖代码块赋值,更利于单元测试和不可变设计
- 复杂初始化逻辑可提取为私有静态方法或私有实例方法,保持代码块简洁
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











