前言
Java中的四大引用是Java面试中的热门考点,今天我们结合生活中的小栗子来重温一下这块知识。
我说白了,我白说了😂。Java中的引用类型就像是我们和对象之间的"关系强度",决定了垃圾回收器(GC)什么时候能带走这个对象。我用现实生活中的关系来比喻这四种引用,配合代码例子带大家彻底理解。
强引用(结婚证关系)
强引用是Java程序中最常见的引用类型,也是默认的引用方式。
特点:只要结婚证在,夫妻关系就永远存在
// 强引用就像结婚
public class StrongReferenceDemo {
public static void main(String[] args) {
// 领结婚证(创建强引用)
Object 老公 = new Object();
// 想离婚必须主动去民政局
laogong= null;
// 现在GC才能来回收这个"laogong"对象
System.gc();
}
}
现实生活中:
- 你和你对象领了结婚证(强引用)
- 只要不离婚(不置null),法律上你们永远是夫妻
- 民政局(GC)没有权利单方面解除你们的婚姻关系
软引用(恋爱关系)
软引用用来描述一些还有用但非必需的对象。
特点:平时甜甜蜜蜜,遇到现实压力(内存不足)可能分手
// 软引用就像谈恋爱
public class SoftReferenceDemo {
public static void main(String[] args) {
// 开始谈恋爱
SoftReference<Object> girlfriend= new SoftReference<>(new Object());
System.out.println("热恋期:" + girlfriend.get()); // 能约到女朋友
try {
// 生活压力背上房贷(内存不足)
Object[] fangdai= new Object[Integer.MAX_VALUE];
} catch (OutOfMemoryError e) {
System.out.println("压力太大后:" + girlfriend.get()); // null,女朋友跑了
}
}
}
现实生活中:
- 谈恋爱没有法律约束(软引用)
- 平时相处和正常关系没区别
- 一旦你经济困难(内存不足),对方可能离开
使用场景:
- 缓存朋友圈照片(内存够就留着,不够就删)
- 浏览器网页缓存
弱引用(朋友关系)
弱引用比软引用更弱一些,只能生存到下一次垃圾回收发生之前。
特点:说散就散,GC一来立刻结束
// 弱引用就像酒肉朋友
public class WeakReferenceDemo {
public static void main(String[] args) {
// 交了个朋友
WeakReference<Object> jiurouFriend= new WeakReference<>(new Object());
System.out.println("聚餐时:" + jiurouFriend.get()); // 还能约出来
System.gc(); // 破产了
System.out.println("破产后:" + jiurouFriend.get()); // null,朋友消失了
}
}
现实生活中:
- 酒肉朋友(弱引用)只能同享福
- 你一出事(GC),他们就马上消失了
- 比谈恋爱(软引用)更脆弱
虚引用(阴阳两界关系)
虚引用是最弱的一种引用关系,也被大家称为"幽灵引用"。
特点:对象已经"死了",但想知道葬礼什么时候举行
// 虚引用就像阴阳眼
public class PhantomReferenceDemo {
public static void main(String[] args) {
// 阴间使者观察名单(引用队列)
ReferenceQueue<Object> yinjian= new ReferenceQueue<>();
// 给活人贴上符咒
Object zhangsan = new Object();
PhantomReference<Object> fuzhou= new PhantomReference<>(zhangsan , yinjian);
System.out.println("活人能看见吗?" + fuzhou.get()); // 永远null
zhangsan = null; // 张三寄了
System.gc();
// 检查阴间使者有没有来收人
Reference<?> guihun = yinjian.poll();
if(guihun != null) {
System.out.println("张三的葬礼可以安排了");
}
}
}
特殊机制:
- 就像阴阳眼,你看不见鬼(get()返回null)
- 但能知道谁死了(通过队列收到通知)
- 适合在对象死后执行清理工作
引用队列(ReferenceQueue)
引用队列可以与软引用、弱引用和虚引用一起使用,用于在对象被回收后收到通知。
工作原理 :
创建引用时关联一个ReferenceQueue
当引用对象被垃圾回收后,引用本身会被加入队列
程序可以通过轮询队列来获知对象被回收的事件
ReferenceQueue<Object> queue = new ReferenceQueue<>();
WeakReference<Object> weakRef = new WeakReference<>(new Object(), queue);
// 监控队列
new Thread(() -> {
try {
Reference<?> ref = queue.remove();
System.out.println("对象已被回收");
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
四种引用对比表
引用类型 | 现实比喻 | GC时的表现 | 能否get()获取 | 典型应用 |
---|---|---|---|---|
强引用 | 领结婚证 | 死也不分开 | 能 | 普通对象创建 |
软引用 | 谈恋爱 | 困难时就分手 | 能 | 缓存 |
弱引用 | 酒肉朋友 | 说散就散 | 能 | WeakHashMap/临时缓存 |
虚引用 | 阴阳眼观亡魂 | 死后才通知 | 不能 | 资源回收监控 |
这样是不是好记多了?每种引用都有适合的场景,就像人际关系也要分亲疏远近~
本篇文章到这里就结束了,欢迎大家点赞收藏关注,感谢各位小伙伴们的支持!