示例代码以下:java
import java.lang.ref.PhantomReference; import java.lang.ref.Reference; import java.lang.ref.ReferenceQueue; /** * @author chenjc * @since 2020-01-13 */ public class PhantomReferenceTest { public static void main(String[] args) throws InterruptedException { User user = new User(1, "debo"); ReferenceQueue<User> userReferenceQueue = new ReferenceQueue<>(); // 创建User对象的虚引用 PhantomReference<User> phantomReference = new PhantomReference<>(user, userReferenceQueue); // 去掉强引用 user = null; System.out.println(phantomReference.get()); // 手动触发GC System.gc(); System.out.println("GC: " + phantomReference.get()); Reference<? extends User> reference = userReferenceQueue.remove(1000); if (reference != null) { System.out.println("对象User被回收了"); } } private static class User { private Integer id; private String name; public User(Integer id, String name) { this.id = id; this.name = name; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "User{" + "id=" + id + ", name='" + name + '\'' + '}'; } } }
输出以下:web
null GC: null 对象User被回收了
能够发现,在GC以前调用phantomReference.get()也没法得到User对象,虚引用就和没有引用同样。那么虚引用存在的意义是什么呢?当GC准备回收对象时,若是发现该对象存在虚引用,就会在回收对象后,将这个虚引用加入引用队列,以通知应用程序对象回收状况,因此也能够将一些资源释放和记录操做放到虚引用中执行。ide