簡単な(大雑把な)例で概念を説明するには、次のことを考慮してください。
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);
...
}
}
thenの作成者がハンドラの処理が完了したときにMyClass
呼び出すのを忘れた場合、 は登録されたインスタンスを永遠に参照し、が破棄されるかアプリケーションが終了するまでメモリに残ります。unregisterChangeHandler()
FileMonitor
HashSet
FileMonitor
これを防ぐために、Bloch は の代わりに弱参照コレクションを使用することを提案していHashSet
ます。これにより、 のインスタンスMyClass
が破棄された場合、参照がモニターのコレクションから削除されます。
HashSet
inFileMonitor
を aに置き換えてWeakHashMap
、ハンドラーをキーとして使用することもできます。後者は、オブジェクトへの他のすべての参照がなくなったときにコレクションからハンドラーを自動的に削除するためです。