虚引用是Java中四种引用类型之一,是一种比弱引用还弱的引用类型。它的主要作用是帮助跟踪对象的销毁过程,但不能通过虚引用访问到对象。在Java中,虚引用被用于在对象被销毁之前进行必要的清理工作,例如关闭文件、释放系统资源等任务。
虚引用通常会被用在以下情况中:
- 在对象销毁的同时,进行一些资源释放操作。
- 追踪对象被垃圾回收机制回收的过程,进而查看对象的回收状态。
- 当虚引用指向的对象被垃圾回收器回收时,虚引用将被放入一个队列中,用于进一步的处理。
使用虚引用,需要注意以下几点:
- 虚引用必须与引用队列(ReferenceQueue)一起使用,虚引用指向的对象被垃圾回收时,将被加入到引用队列中,程序可以在引用队列中获取到虚引用。与ReferenceQueue配合使用,可以实现一些比较复杂的操作,例如资源释放、对象的自我复活等。
- 虚引用不能用来取得对象的引用,因为虚引用所指向的对象随时可能被垃圾回收机制回收。
- 虚引用的get()方法始终返回null。
下面是两个虚引用的示例:
示例1
Object obj = new Object();
ReferenceQueue<Object> queue = new ReferenceQueue<>();
WeakReference<Object> weakRef = new WeakReference<>(obj, queue);
PhantomReference<Object> phantomRef = new PhantomReference<>(obj, queue); //创建一个虚引用
obj = null; //让对象成为“垃圾”
System.gc(); //通知JVM的垃圾回收器进行垃圾回收
//检查队列中是否有虚引用
Reference<?> ref = queue.poll();
while (ref != null) {
System.out.println("queue中的引用对象: " + ref);
// 被关联的对象被清除后,虚引用才会被添加至队列中
if (ref == phantomRef) {
System.out.println("phantom reference被加入到了队列中");
}
if (ref == weakRef) {
System.out.println("weak reference被加入到了队列中");
}
ref = queue.poll();
}
运行示例1,输出如下:
weak reference被加入到了队列中
phantom reference被加入到了队列中
从输出结果中可以看出,被弱引用和虚引用所引用的对象被回收后,这些引用都被加入到了队列中。
示例2
import java.lang.ref.PhantomReference;
import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;
public class PhantomRefTest {
public static void main(String[] args) {
Object obj = new Object();
ReferenceQueue<Object> queue = new ReferenceQueue<>();
PhantomReference<Object> phantomRef = new PhantomReference<>(obj, queue);
obj = null;
System.gc();
Reference<?> ref = queue.poll();
while (ref != null) {
System.out.println("queue中的引用对象: " + ref);
if (ref == phantomRef) {
System.out.println("对象被垃圾回收了");
}
ref = queue.poll();
}
}
}
运行示例2,输出如下:
queue中的引用对象: java.lang.ref.PhantomReference@74a14482
对象被垃圾回收了
从输出结果可以看出,当虚引用所引用的对象被垃圾回收机制回收时,这个虚引用将被加入到引用队列中,并可以在队列中获取到它。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:什么是虚引用? - Python技术站