Q: What are weak references good for?
A: They have something to do with garbage collection.
While the answer above is certainly better than not knowing about weak references at all; any aspiring senior Java developer should know a bit more about them. Especially, when we consider that they are around since Java version 1.2. So, let’s dive a little deeper into this topic.
Strong references are ordinary Java references we use every day. For example:
Widget widget = new Widget();
Objects survive garbage collection and stay in the memory heap as long as they are reachable through strong references.
Weak references are not strong enough to keep the objects from being garbage-collected. You can create a weak reference like this:
weakWidget = new WeakReference (widget);
In order to get back the actual widget, you call
weakWidget.get(). Because the widget can get garbage-collected at any time, such a call can suddenly start returning
null. There is a related class
WeakHashMap where the keys (not the values!) are weak references and when the key gets garbage-collected the value is removed from the map automatically. This behavior makes it an ideal candidate for implementing cache functionality.
Would you like to know when a weakly referenced object has been garbage collected? This is what
ReferenceQueue is for. If you pass it into the constructor of a weak reference it will be automatically put on the queue once the referenced object becomes a garbage.
There are different degrees of weakness. Soft references are between strong and weak references. They are less eager to throw away their object. In practice, they retain it as long as there is plenty of memory – but this is not a guarantee.
Phantom references are the weakest form of a reference: their
get() method always returns
null. Phantom references are only enqueued when the object has been already finalized. Which leads us to the only scenario I can think of in which phantom references can be useful: to determine when exactly a given object has been garbage-collected. You can create a phantom reference calling it’s only constructor:
PhantomReference(T referent, ReferenceQueue< ? Super T> q)
Did you notice something? Unlike soft and weak references, phantom references are not automatically cleared by the garbage collector as they are enqueued. An object that is reachable via phantom references will remain so until all such references are cleared or themselves become unreachable .
I Hope you found this post useful 😉