I'm implementing some behavior which could benefit from using weak references some of the time. I'd like the user of the class to be able to indicate at construction time whether this is the case or not. Since WeakReference
extends Reference
at first glance it would seem I could do something like (this is a mockup, not what I'm actually trying to do):
public class Container<T> {
private boolean useWeakRef;
private Reference<T> ref;
public Container(boolean isWeak) {
useWeakRef = isWeak;
}
public void store(T val) {
if(useWeakRef) {
ref = new WeakReference<>(val);
} else {
ref = new StrongReference<>(val);
}
}
// May return null
public T get() {
return ref.get();
}
}
However there is no StrongReference
class, and according to the Reference javadocs:
Because reference objects are implemented in close cooperation with the garbage collector, this class may not be subclassed directly.
So I can't create my own subclass of Reference that holds a strong (i.e. normal) reference to the object. This seems to mean it's not possible to make a class which hides whether it uses Weak (or Soft) references from the caller.
I don't really understand why this class doesn't exist, a StrongReference
object should simply always return the object from get() unless clear() has been called. Why is this missing? Is a StrongReference
inconsistent with Reference
in some way? It would make building generic reference-holder objects much simpler.
A weak reference permits the garbage collector to collect the object while still allowing the application to access the object. A weak reference is valid only during the indeterminate amount of time until the object is collected when no strong references exist.
According to Apple's docs: “Use a weak reference whenever it is valid for that reference to become nil at some point during its lifetime. Conversely, use an unowned reference when you know that the reference will never be nil once it has been set during initialization.”
strong reference (plural strong references) (computing) a reference that does protect the referenced object from collection by a garbage collector.
Pointers that are not retained are often referred to as “weak” in Objective-C documentation that predates the garbage collector. These are references that are allowed to persist beyond the lifetime of the object. Unfortunately, there is no automatic way of telling whether they are still valid.
A strong reference is one of the types of references that has the highest level of importance. Garbage collection does not select an object that has an active strong reference to it except when it uses cylindrical references. This statement creates a strong reference to the newly created object ‘Student’.
Contrary to strong reference, weak reference has no impact on an object’s reference count. Meaning that if we declare a weak variable pointing to an object, that object’s reference count will remain the same as it was before. Lets see what that means in practice with the following simple example:
When the strong references count goes to zero, the object will release all the references it has but the object’s own memory won’t be released while there are unowned references pointing to it. The object’s memory is marked as zombie though.
A weak reference comes into the picture when an object without any other references needs to be removed from the memory. If the garbage collector finds an object with only weak references, it marks that object for deallocation from the memory. The above example creates a DBConnection object and a weak reference, weakStu, to the DBConnection object.
When i've needed to do this, i just created a custom Reference interface and a trivial subclass of WeakReference. it's annoying but it's about as good as you can do.
public interface MyReference<T> {
public T get();
}
public class MyWeakReference<T> extends WeakReference<T> implements MyReference<T> {
}
public class MyStrongReference<T> implements MyReference<T> {
// obvious implementation here ...
}
UPDATE:
to clarify, i have no idea why this wasn't included in the jdk in the first place (i, too, wish it had been), however, i feel this is a reasonable workaround.
for those seeking justification of this idea, i have found it necessary when implementing custom caches where the strength of the reference is part of the configuration for the cache.
You cannot subclass Reference because it does not have any public / protected constructors. But there's a workaround:
class StrongReference<T> extends WeakReference<T> {
private final T referent;
StrongReference(T referent) {
super(null);
this.referent = referent;
}
@Override
public T get() {
return referent;
}
// implement other methods
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With