[英]Understanding singletons class in Java
在閱讀Effective Java時,我發現實現單例的最有用方法只是使用具有單個INSTANCE
enum
。 但是如果需要將其設為一個類,根據他的一些懷疑,完美的可序列化線程安全的單例類將如下所示:
public class SerializableSingletonClass implements Serializable{
private static final long serialVersionUID = 1L;
private int value;
private String name;
private SerializableSingletonClass(int value, String name) {
if( value < 0 ) throw new IllegalArgumentException("Value may not be less than 0");
this.value = value;
this.name = Validate.notNull(name, "Name may not be null");
}
private static class SerializableSingletonHolder{
public static final SerializableSingletonClass INSTANCE;
static {
INSTANCE = new SerializableSingletonClass(0, "default");
}
}
private void readObject(ObjectInputStream stream) throws InvalidObjectException{
throw new InvalidObjectException("proxy required");
}
private Object writeReplace(){
return new SerializationProxy(this);
}
private static class SerializationProxy implements Serializable{
private static final long serialVersionUID = 1L;
public SerializationProxy(SerializableSingletonClass ignored) { } //Here is the question
private Object readResolve(){
return SerializableSingletonHolder.INSTANCE;
}
}
}
據我所知,他建議只用當前使用的實例替換序列化的實例。
因此,為什么我們永遠都不能使單例序列化,因為它們的序列形式將永遠不會被使用。 我們只是將其丟棄,並用當前實例替換反序列化的實例。
對我來說,實現可序列化單例的問題看起來只是一個理論上的問題。 根據我的說法,對單例進行反序列化沒有多大意義(對於enum
)。
那我想念什么呢? 您能否詳細解釋一下?
如果您在其他一些可序列化的類中有某個字段存儲該單例實例,並且想要對該類進行序列化/反序列化,則始終必須標記該字段為transient
,並確保在反序列化時手動填充它。 如果在Singleton中處理它,則不必這樣做。 我想這就是可序列化單例的原因。
枚舉也可以序列化,而不是它們的字段。
我認為保持簡單和易於維護非常重要,例如,如果要保存它,請使用文本文件。
我將添加一個保存和加載之類的方法(可能帶有文件名)
enum SaveableSingleton {
INSTANCE;
String name;
int value;
public void load(String filename) throws IOException {
try (Scanner scanner = new Scanner(new File(filename))) {
name = scanner.nexLine();
value = scanner.nextInt();
}
}
public void save(String filename) throws IOException {
try (PrintWriter pw = new PrintWriter(new File(filename))) {
pw.println(name);
pw.println(value);
}
}
}
創建一個像
my-name-is
12345
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.