《Java 100 天进阶之路》第20篇:Java初始化、构造器、对象创建的过程

第20篇:Java初始化、构造器、对象创建的过程


📌 系列导航《Java 100 天进阶之路》完整目录 |

⬅️ 上一篇:第19篇:Java接口的作用和意义 |

➡️ 下一篇:第21篇:Java Object类


一、核心知识点

  • 成员初始化顺序:
    • 静态成员(静态变量、静态代码块)在类加载时执行,按声明顺序执行
    • 实例成员(实例变量、实例代码块)在创建对象时执行,在构造方法之前执行
    • 构造方法最后执行
  • 构造器(构造方法)的作用:初始化对象状态
  • 对象创建的完整流程(JVM 角度):
    1. 类加载检查(如果类未加载,先加载)
    2. 堆中分配内存
    3. 设置默认值(零值)
    4. 设置对象头(类型指针、GC 信息等)
    5. 执行实例初始化:实例变量显式赋值 → 实例代码块 → 构造方法
  • 父子类初始化顺序:先父类静态 → 子类静态 → 父类实例变量/代码块 → 父类构造 → 子类实例变量/代码块 → 子类构造

二、通俗讲解(1分钟开心学)

1. 初始化过程就像"盖房子"

  • 类加载:先设计图纸(静态成员),只做一次。
  • 对象创建:每次建房,都要打地基(默认值)、砌墙(显式赋值)、内部装修(实例代码块)、最后交房(构造方法)。

2. 静态成分(类级别)

当你第一次使用一个类时(new、访问静态变量/方法、Class.forName等),JVM 会加载这个类,并执行:

  • 静态变量赋值
  • 静态代码块(按代码顺序)

3. 实例成分(对象级别)

每次 new 一个对象,都会执行:

  • 实例变量显式赋值
  • 实例代码块({ ... } 中的内容,按顺序)
  • 构造方法

4. 继承时的顺序

想象你创建子类对象,必须先给父类"打好地基":

父类静态 → 子类静态 → 父类实例初始化 → 父类构造 → 子类实例初始化 → 子类构造

面试口诀

"父静子静,父实父构,子实子构"

三、实操代码案例 + 场景说明

场景:通过打印日志,直观看到初始化的完整顺序。

1. 单个类的初始化顺序

java 复制代码
class Student {
    private String name = initName();   // 实例变量显式赋值
    private static int counter = initCounter();  // 静态变量
    
    static {
        System.out.println("2. 静态代码块执行");
    }
    
    {
        System.out.println("4. 实例代码块执行");
    }
    
    public Student() {
        System.out.println("5. 构造方法执行");
    }
    
    private static int initCounter() {
        System.out.println("1. 静态变量赋值 (initCounter)");
        return 0;
    }
    
    private String initName() {
        System.out.println("3. 实例变量赋值 (initName)");
        return "默认";
    }
}

// 执行 new Student() 输出:
// 1. 静态变量赋值
// 2. 静态代码块执行
// 3. 实例变量赋值
// 4. 实例代码块执行
// 5. 构造方法执行

2. 继承时的完整顺序

java 复制代码
class Parent {
    static { System.out.println("A. 父类静态块"); }
    { System.out.println("C. 父类实例块"); }
    Parent() { System.out.println("D. 父类构造方法"); }
}

class Child extends Parent {
    static { System.out.println("B. 子类静态块"); }
    { System.out.println("E. 子类实例块"); }
    Child() { System.out.println("F. 子类构造方法"); }
}

// 执行 new Child() 输出:
// A. 父类静态块
// B. 子类静态块
// C. 父类实例块
// D. 父类构造方法
// E. 子类实例块
// F. 子类构造方法

3. 对象创建的内存流程(代码配合注释)

java 复制代码
public class MemoryProcess {
    private int value = 100;   // ① 默认值0 → ② 显式赋值为100
    private String text;       // 默认null,没有显式赋值
    
    public MemoryProcess(String text) {
        this.text = text;      // ③ 构造方法中赋值
    }
}
// 执行 new MemoryProcess("hello"):
// 1. 堆中分配内存
// 2. value = 0, text = null (默认值)
// 3. value = 100 (显式赋值)
// 4. text = "hello" (构造方法)

四、避坑要点

错误/误区 后果 正确做法
在静态代码块中访问实例成员 编译错误 静态上下文只能访问静态成员
实例代码块中抛出未捕获异常 对象创建失败,异常传播给调用者 尽量不在实例代码块中写复杂逻辑
构造方法中调用可被子类重写的方法 子类未初始化完成,可能空指针 只调用 privatefinal 方法
this()super() 同时出现在构造方法中 编译错误 只能选其一,且必须在第一行

五、面试高频考点

Q1:静态代码块、实例代码块、构造方法的执行顺序?

类加载:静态代码块。对象创建:实例变量显式赋值和实例代码块(按顺序) → 构造方法。继承时先父类后子类。

Q2:一个对象创建时,内存中发生了什么?

① 类加载(如果没加载)→ ② 堆中分配内存 → ③ 成员变量设默认值 → ④ 设置对象头 → ⑤ 实例初始化(显式赋值、实例代码块、构造方法)。

Q3:构造方法中调用普通方法有什么风险?

如果该方法被子类重写,调用时会执行子类版本,而此时子类的成员可能尚未初始化(null 或 0),导致逻辑错误或空指针。

六、练习题

  1. 预测输出

    java 复制代码
    class A {
        static { System.out.print("A1 "); }
        { System.out.print("A2 "); }
        A() { System.out.print("A3 "); }
    }
    class B extends A {
        static { System.out.print("B1 "); }
        { System.out.print("B2 "); }
        B() { System.out.print("B3 "); }
    }
    public class Test { public static void main(String[] args) { new B(); } }
  2. 代码改错 :下面代码哪里有问题?如何修正?

    java 复制代码
    class Base {
        public Base() { print(); }
        void print() { System.out.println("Base"); }
    }
    class Derived extends Base {
        private String value = "Hello";
        @Override void print() { System.out.println(value.toUpperCase()); }
    }
  3. 动手 :写一个类,包含静态代码块、实例代码块、构造方法,并在 main 中创建多个对象,观察输出。


📊 你的学习进度

  • 当前:第20篇 / 共44篇 · 第二阶段:核心语法与面向对象(第5~20篇)
  • ✅ 已完成:第1~19篇
  • 📖 正在学:第20篇
  • ⏳ 待学习:第21~44篇

👉 📚 完整目录 & 学习指南 | 🔥 订阅本专栏,不错过每一篇

💡 本专栏每篇都包含:避坑表 + 面试高频考点 + 练习题。每天30分钟,100天拿offer!


👉 下一篇预告

《Java Object类》

内容简介:toString、equals、hashCode的正确重写规范,equals与hashCode的契约,getClass、clone方法。

💡 学完这篇,你将掌握所有类的共同"祖先",写出规范的Java Bean。

📌 《Java 100 天进阶之路 | 从入门到上岗就业》 每天一篇,建议收藏 + 关注 ,一起100天拿offer!

👉 点击关注我,更新后第一时间收到推送!

相关推荐
月落归舟1 小时前
深入解析Java基础之基础
java·开发语言
Lee川1 小时前
从输入框到智能匹配:一文读懂搜索功能的完整实现
前端·后端
南宫萧幕1 小时前
基于 Simulink 与 Python 联合仿真的 eVTOL 强化学习全链路实战
开发语言·人工智能·python·算法·机器学习·控制
电魂泡哥1 小时前
CMS垃圾回收
java·jvm·算法
csbysj20201 小时前
Perl 运算符
开发语言
Amctwd1 小时前
【Python】从Excel中按行提取图片
java·python·excel
啃臭2 小时前
AOP和反射
java·spring boot
朝阳392 小时前
React【面试】
前端·react.js·面试
西凉的悲伤2 小时前
java 使用PNG图片隐写文件
java·图片隐写·png