2012-03-30 4 views
3

Мы продолжаем читать о том, как использовать readResolve() для обеспечения единства в случае сериализации Singleton. Но каковы практические примеры использования сериализации Singleton в первую очередь?Java: практические инструменты для сериализации Singletons?

EDIT: pl. примечание: вопрос о почему для сериализации Singleton и не о том, что это безопасный способ сделать это.

ответ

1

Объект может быть одноэлементным, но он может быть частью более крупной структуры, которая не совсем знает. Например, он может реализовать интерфейс, который может иметь несколько различных реализаций (и, таким образом, экземпляры):

interface StringSink extends Serializable { void dump(String s); } 

class MultiDumper implements Serializable { 
    private final StringSink sink; 
    public MultiDumper(StringSink sink){ this.sink = sink; } 
    void doSomeStuff(Collection<String> strings){ 
     for (String s : strings) sink.dump(s); 
    } 
} 

Теперь предположим, что мы хотим StringSink, который сбрасывает строки на стандартный вывод. Поскольку существует только один стандартный вывод, мы могли бы также сделать его одноплодной:

/** Beware: Not good for serializing! */ 
class StdoutStringSink { 
    public static final StdoutStringSink INSTANCE = new StdoutStringSink(); 
    private StdoutStringSink(){} 
    @Override 
    public void dump(String s){ System.out.println(s); } 
} 

И мы используем это следующим образом:

MultiDumper dumper = new MultiDumper(StdoutStringSink.INSTANCE); 

Если вы сериализации, а затем десериализации этот самосвал, вы» d имеют два экземпляра StdoutStringSink, плавающих в вашей программе.

2

Joshua Bloch Effective Java (2nd Edition) предлагает использовать Enum как singleton. Он всегда создается VM, и невозможно (или сложно) создать второй экземпляр singleton.

Для нормальной одноплодной всегда можно «взломать» систему, см:

Singleton Pattern

Hot Spot: 
Multithreading - A special care should be taken when singleton has to be used in a multithreading application. 
Serialization - When Singletons are implementing Serializable interface they have to implement readResolve method in order to avoid having 2 different objects. 
Classloaders - If the Singleton class is loaded by 2 different class loaders we'll have 2 different classes, one for each class loader. 
Global Access Point represented by the class name - The singleton instance is obtained using the class name. At the first view this is an easy way to access it, but it is not very flexible. If we need to replace the Sigleton class, all the references in the code should be changed accordinglly. 
+0

Спасибо за ответ, но мой вопрос больше о * why * для сериализации Singleton, чем о том, как это сделать. Изменит вопрос, чтобы отразить это. – shrini1000

+0

Для gwt, jpa, hibernate например :) и других фреймворков, которые отправляют его по сети. –

+0

Конкретный пример/ссылка на один поможет. :) – shrini1000

3

Самым распространенным случаем будет, где у вас есть объект, представляющий структуру больших данных (например, дерево узлов в документе в стиле XML).

Эта структура данных может легко содержать однотонные значения (например, одиночные экземпляры, которые представляют тип данных конкретного атрибута, прикрепленного к узлу в дереве). Многие разные узлы в дереве могут указывать на одно и то же общее одноэлементное значение.

Есть много обстоятельств, когда вы можете сериализовать такую ​​структуру данных, например. отправка копии объекта по сети. В этом случае вам также потребуется сериализовать значения singleton.

Но тогда, когда вы читаете структуру данных обратно, вы хотите использовать существующее значение singleton, а не только что созданный экземпляр. Вот почему вам нужно readResolve()

Смежные вопросы