JavaSE从0到1-DAY1.1-Java对象与内存
·
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]
↓ ↑
传参时复制的是 同一块内存
这个引用值
更多推荐

所有评论(0)