Consider the following code:
public static final ReferenceQueue<Object> REF_QUEUE = new ReferenceQueue<>();
public class Foo extends PhantomReference<Object> {
public Foo(Object obj) { super(obj, REF_QUEUE); }
}
public class Bar {
private Foo foo;
public void refTest() {
foo = new Foo(new Apple("Cortland"));
foo = null;
}
}
The documentation for PhantomReference says that:
If the garbage collector determines at a certain point in time that the referent of a phantom reference is phantom reachable, then at that time or at some later time it will enqueue the reference.
In the refTest method, however, the Cortland Apple becomes unreachable -- not phantom reachable -- because the Foo that contains it is unreachable. Will the Foo object be queued on REF_QUEUE?
That’s addressed explicitly in the documentation
So if you don’t keep a reference to the
PhantomReference, its memory gets reclaimed like with any other ordinary object and it will never get enqueued.Since a garbage collector works by traversing all reachable objects, it will simply enqueue a phantom reference when it encounters it and finds, at the end of the traversal, that its referent has not been encountered through other references. If it doesn’t encounter the phantom reference, nothing will happen.