クラス「A」をシングルトンとして定義した場合、クラス「A」のオブジェクトを 1 つだけ作成できます。シリアル化可能にしてシリアル化した場合、同じオブジェクトのシングルトン状態を達成するにはどうすればよいですか?
3 に答える
引用Effective Java #77
すると、実装readResolve
方法を確認する必要があります。
readResolve 機能を使用すると、readObject によって作成されたインスタンスを別のインスタンスに置き換えることができます [Serialization, 3.7]。デシリアライズされるオブジェクトのクラスが適切な宣言で readResolve メソッドを定義する場合、デシリアライズ後に新しく作成されたオブジェクトでこのメソッドが呼び出されます。このメソッドによって返されるオブジェクト参照は、新しく作成されたオブジェクトの代わりに返されます。この機能のほとんどの使用では、新しく作成されたオブジェクトへの参照は保持されないため、すぐにガベージ コレクションの対象になります。
public class Elvis implements Serializable {
public static final Elvis INSTANCE = new Elvis();
// readResolve for instance control - you can do better!
private Object readResolve() {
//Return the one true Elvis and let the garbage collector
// take care of the Elvis impersonator.
return INSTANCE;
}
}
オブジェクトの逆シリアル化の前に呼び出されるメソッドは readResolve() であるため、実際に逆シリアル化せずに、このメソッドから同じ状態オブジェクトを単純に返すことができます。
下記を参照してください、
public final class MySingleton {
private MySingleton() { }
private static final MySingleton INSTANCE = new MySingleton();
public static MySingleton getInstance() { return INSTANCE; }
private Object readResolve() throws ObjectStreamException {
// instead of the object we're on,
// return the class variable INSTANCE
return INSTANCE;
}
}
シングルトンの一意性を保証するには、新しくデシリアライズされたオブジェクトではなく、シングルトン オブジェクトを返すためのメソッドのSerializable
カスタマイズが必要になる場合があります。readResolve
一方、書籍「Effective Java」Item77 は、次のことを示唆しています。
インスタンス コントロールの場合、readResolve よりも列挙型を優先する