According to ‘Effective Java, 2nd Edition’, “ … The best way to ensure that callbacks are garbage collected promptly is to store only weak refer- ences to them, for instance, by storing them only as keys in a WeakHashMap.”
There is an example in JDK source code which uses WeakHashMap to save callbacks to prevent memory leak.
Let’s look at the class
BaseResourceFactory
There is a field: listenerMap
, which is a WeakHashMap that saves listeners that are being added.
// Use a WeakHashMap as it automatically removes dead objects when they're// collectedprivate final WeakHashMap<ResourceFactoryListener,Boolean> listenerMap =new WeakHashMap<ResourceFactoryListener,Boolean>();
To add a listener, the client just need to save the listener as the key, and Boolean.TRUE as the value to the map.
@Override public void addFactoryListener(ResourceFactoryListener l) {listenerMap.put(l, Boolean.TRUE);}
Why using Boolean.TRUE?
Because it is a constant object:
public static final Boolean TRUE = new Boolean(true);
So we are using it as a placeholder without creating any additional object or using any additional memory.
And to get all listeners, the getFactoryListeners method returns a defensive copy of the keySet of the WeahHashMap.
protected ResourceFactoryListener[] getFactoryListeners() {return listenerMap.keySet().toArray(new ResourceFactoryListener[0]);}
Lastly, there is remove method.
@Override public void removeFactoryListener(ResourceFactoryListener l) {// remove will return null if there is no mapping, so it's safe to call// with unregistered listenerslistenerMap.remove(l);}