一聚教程网:一个值得你收藏的教程网站

最新下载

热门教程

Java对象实例化完整过程:从静态块到构造函数的顺序解析

时间:2026-06-24 08:42:03 编辑:袖梨 来源:一聚教程网

Java对象初始化顺序为:父类静态变量→父类静态块→子类静态变量→子类静态块→父类实例变量→父类实例块→父类构造器→子类实例变量→子类实例块→子类构造器;静态部分仅执行一次,实例部分每次new均执行。

Java对象实例化不是“调用构造函数”就完事,而是一套分阶段、有依赖、不可跳过的执行链条。真正决定对象能否正确创建的,是静态块、实例块、字段赋值和构造函数之间严格的先后关系。

类加载阶段:静态部分只跑一次

当JVM首次主动使用某个类(比如第一次 new、调用静态方法、访问静态字段),就会触发类加载与初始化。这个阶段只发生一次,且严格按继承顺序执行:

  • 父类静态变量赋值 → 父类静态代码块(按源码顺序)
  • 子类静态变量赋值 → 子类静态代码块(按源码顺序)

此时还没有任何对象产生。所有静态成员共享同一份内存,适合做全局配置、连接池初始化、驱动注册等一次性操作。注意:final static基本类型常量(如public static final int PORT = 8080;)属于编译期常量,不触发类初始化。

对象创建阶段:每次new都重走父→子链路

当你写new Child()时,JVM开始构建具体对象,执行顺序固定为:

立即学习“Java免费学习笔记(深入)”;

  • 父类实例变量赋值 → 父类实例代码块(按源码顺序)
  • 父类构造函数(含隐式或显式的super()调用)
  • 子类实例变量赋值 → 子类实例代码块(按源码顺序)
  • 子类构造函数

实例代码块(即不带static的{})会被编译器自动插入到每个构造方法开头(在super()之后、构造体之前),所以它总能安全访问已初始化的字段和this引用。多个实例块也按声明顺序执行,父类的一定先于子类。

普通代码块:不在初始化流程里

写在方法内部的{ ... }只是局部作用域语法,比如放在main或构造函数里。它不参与类加载或对象构建,纯属运行时顺序执行,变量作用域仅限块内。这类块不影响初始化逻辑,也不受继承影响,和“对象怎么造出来”完全无关。

为什么顺序不能乱?关键细节在这里

理解顺序的核心在于区分“类就绪”和“对象诞生”两个阶段:

  • 静态块里不能用this或非静态成员——因为对象还没影子
  • 实例块里可以调用实例方法、读写普通字段——因为字段赋值已完成、对象已分配内存
  • 子类静态块能安全使用父类public static字段,但父类静态块绝不能依赖子类静态状态——双亲委派机制保障了加载顺序
  • 即使你只new Child(),父类也会被强制加载并执行静态初始化

这些规则不是设计选择,而是JVM规范强制要求。绕过它,轻则字段为null、配置未生效,重则类加载失败或逻辑错乱。

热门栏目