Java中四种引用类型按强度递减为:强引用(GC绝不回收,即使OOM)、软引用(内存不足时回收,适合缓存)、弱引用(GC时立即回收,用于临时对象)、虚引用(无法获取对象,仅用于回收通知)。

引用不是对象,只是地址的“别名”
在 Java 中,声明 String s = new String("hello") 时,变量 s 本身不存字符串内容,只存一个整数——这个整数是堆中那个字符串对象的起始内存地址(比如 0x7f8a12b4)。就像门牌号不等于房子,引用也不等于对象。真正存放数据的是堆内存;而 s 这个引用变量,连同其他局部变量(如 int、boolean)一起,保存在当前线程的虚拟机栈里。
四类引用决定对象能否被回收
Java 的垃圾回收器(GC)是否回收一个对象,关键看它是否还被“有效引用”着。JVM 定义了四种强度递减的引用类型:
- 强引用:最常见,如 Object obj = new Object()。只要该引用还活着(没被赋 null、没出作用域),GC 绝对不碰它,哪怕 OOM 也先抛异常
- 软引用:用 SoftReference 包装。内存充足时不回收;快撑不住时,GC 会优先清理它——适合做图片缓存、网页资源缓存
- 弱引用:用 WeakReference 包装。只要 GC 线程启动,不管内存够不够,都会回收关联对象——常用于 WeakHashMap 或临时监听器的自动解绑
- 虚引用:用 PhantomReference 包装,且必须配合 ReferenceQueue 使用。它的 get() 永远返回 null,无法取对象;唯一作用是让程序在对象被回收前收到通知,做清理(如关闭文件句柄、释放 native 内存)
传参时传递的是引用的副本,不是对象本身
方法调用传引用类型参数,本质是把栈中那个地址值拷贝一份给形参。所以:
当用户要求为 Java 代码添加注释、修改注释、审查注释、整理注释格式,或要求按照代码注释规范处理 Java 文件时,使用本技能。本技能用于统一生成和维护 Java 类注释模板、按 Git 对比 release 判断版本号、补充每行代码上方中文块注释、调整注释空行规则,并保持 Java 文件 UTF-8 无 BOM 编码。典型触发场景包括:补充类注释、更新 @version、检查 @author 来源、整理行尾注释、把注释放到代码上一行、检查注释是否符合规范、构建前检查 Java 注释风格。
- 修改形参指向的新对象(如 obj = new Object()),不影响实参原来的指向
- 但通过形参修改对象内部状态(如 list.add("x") 或 person.setName("Alice")),实参看到的也是变化后的结果——因为两者指向堆中同一块内存
堆与栈分工明确,共同支撑引用语义
JVM 内存布局决定了引用如何落地:
- 栈(Stack):每个线程独有,存局部变量(包括所有引用变量)、方法调用帧。空间小、速度快、生命周期短
- 堆(Heap):所有线程共享,new 出来的对象实例(及其成员变量)都放这里。空间大、分配/回收慢,由 GC 管理
- 方法区(含运行时常量池):存类结构、静态变量、字符串字面量等。JDK 8 后,字符串常量池已移入堆中
物理内存上,这些区域都映射到操作系统的真实 RAM,但 JVM 通过分代(年轻代/老年代)、GC 算法(如 G1、ZGC)和内存屏障等机制,在逻辑上隔离并高效管理它们。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










