Чтобы проиллюстрировать концепцию на быстром (сыром) примере, рассмотрим следующее:
public interface ChangeHandler {
public void handleChange();
}
public class FileMonitor {
private File file;
private Set<ChangeHandler> handlers = new HashSet<ChangeHandler>();
public FileMonitor(File file) {
this.file = file;
}
public void registerChangeHandler(ChangeHandler handler) {
this.handlers.add(handler);
}
public void unregisterChangeHandler(ChangeHandler handler) {
this.handlers.remove(handler);
}
...
}
Если клиентский класс затем использует этот FileMonitor
API, они могут сделать это:
public class MyClass {
File myFile = new File(...);
FileMonitor monitor = new FileMonitor(myFile);
public void something() {
...
ChangeHandler myHandler = getChangeHandler();
monitor.registerChangeHandler(myHandler);
...
}
}
Если автор MyClass
затем забудет вызвать unregisterChangeHandler()
, когда это будет сделано с обработчиком, FileMonitor
HashSet
всегда будет ссылаться на зарегистрированный экземпляр, заставляя его оставаться в памятидо тех пор, пока FileMonitor
не будет уничтожен или приложение не закроется.
Чтобы предотвратить это, Блох предлагает использовать коллекцию со слабыми ссылками вместо HashSet
, так что если ваш экземпляр MyClass
будет уничтожен,ссылка будет удалена из коллекции монитора.
Вы можете заменить HashSet
in FileMonitor
на WeakHashMap
и использовать обработчики в качестве ключей, так как последний будетавтоматически удаляет обработчик из коллекции, когда все другие ссылки на объект исчезают.