The Java library documentation for the java.lang.ref
package characterizes the decreasing strength of the three explicit reference types.
You use a SoftReference
when you want the referenced object to stay alive until the host process is running low on memory. The object will not be eligible for collection until the collector needs to free memory. Loosely stated, binding a SoftReference
means, "Pin the object until you can't anymore."
By contrast, use a WeakReference
when you don't want to influence the referenced object's lifetime; you merely want to make a separate assertion about the referenced object, so long as it remains alive. The object's eligibility for collection is not influenced by the presence of bound WeakReference
s. Something like a an external mapping from object instance to related property, where the property need only be recorded so long as the related object is alive, is a good use for WeakReference
s and WeakHashMap
.
The last one -- PhantomReference
-- is harder to characterize. Like WeakReference
, such a bound PhantomReference
exerts no influence on the referenced object's lifetime. But unlike the other reference types, one can't even dereference a PhantomReference
. In a sense, it doesn't point to the thing it points to, as far as callers can tell. It merely allows one to associate some related data with the referenced object -- data that can later be inspected and acted upon when the referenced object when the PhantomReference
gets queued in its related ReferenceQueue
. Normally one derives a type from PhantomReference
and includes some additional data in that derived type. Unfortunately, there's some downcasting involved to make use of such a derived type.
In your example code, it's not the ref
reference (or, if you prefer, "variable") that can be null. Rather, it's the value obtained by calling Reference#get()
that may be null. If it is found to be null, you're too late; the referenced object is already on its way to being collected:
final String val = ref.get();
if (null != val)
{
// "val" is now pinned strongly.
}
else
{
// "val" is already ready to be collected.
}