Java 对象与内存学习笔记

总结:对象创建过程、方法栈与内存回收、引用传递、this 本质


一、创建对象的七步

Dog xiaobai = new Dog("小白", 3); 为例:

步骤 说明
1. 加载 class 字节码文件 把 Dog.class 加载到方法区,若已加载则跳过
2. 申明等号左边的局部变量 在栈中为 xiaobai 分配空间(此时还未赋值)
3. 在堆里开辟空间 在堆中为 Dog 对象分配内存
4. 默认初始化属性 根据类型赋默认值:int→0,double→0.0,引用→null 等
5. 显示初始化属性 若类中有 private int age = 1;,则赋 1
6. 利用构造方法初始化属性 执行构造方法中的代码,完成最终初始化
7. 把对象地址赋给变量 把堆中对象的内存地址赋给栈中的 xiaobai

关键:变量 xiaobai 存的是引用(地址),不是对象本身;对象在堆里。


二、方法出栈与内存回收

方法出栈后

  • :方法出栈后,该方法的局部变量全部消失,但涉及堆的变量已经作用
  • :若没有任何变量再指向某对象,该对象成为“垃圾”,由 GC 回收
  • 方法区:class 的字节码信息通常常驻,一般不会消失

简要理解

方法结束 → 栈帧弹出 → 局部变量消失
                ↓
        若该变量是对象的唯一引用
                ↓
        堆中对象无人引用 → 可被 GC 回收

三、对象传递的本质

实际传递的是什么?

传递的是引用(地址),不是对象本身。

void change(Dog d) {
    d.setAge(5);  // 修改的是堆里同一块对象
}
// 调用
Dog xiaobai = new Dog();
change(xiaobai);  // 传进去的是 xiaobai 存的地址

后果

  • 方法内对对象属性的修改,会反映到原对象
  • 因为形参 d 和实参 xiaobai 指向堆里同一个对象

多个变量指向同一对象时

Dog a = new Dog("小白", 3);
Dog b = a;  // b 和 a 指向同一对象
b.setAge(5);
System.out.println(a.getAge());  // 输出 5

会发生:任一变量通过引用修改对象,其他变量“看到”的是同一个对象,修改会同步体现。


四、this 的本质

this 代表“调用当前方法的那个对象”的引用,也就是该对象在堆中的内存地址。

public void setName(String name) {
    this.name = name;  // this = 调用 setName 的 dog 对象的地址
}
// 调用
xiaobai.setName("小黑");  // 此时 this 指向 xiaobai 所指的对象

总结

表述 含义
this 当前对象的引用(地址)
this.xxx 当前对象的成员 xxx
本质 所在方法使用者(调用者)的内存地址

五、小结图

栈                          堆                    方法区
xiaobai ──引用──→ [Dog对象]  ←── this 指向这里    [Dog.class]
  ↓                    ↑
  传参时复制的是       同一块内存
  这个引用值
Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐