Сериализация порождает глубокое клонирование? - PullRequest
2 голосов
/ 23 сентября 2011

Я читал статью, написанную участником ASF, и он вкратце упомянул, что «старый трюк Java» для глубокого клонирования объекта состоит в его сериализации и последующей десериализации в другой объект.Когда я прочитал это, я сделал паузу и подумал: «Эй, это довольно умно».К сожалению, ни глубокое клонирование, ни сериализация не были предметом статьи, и поэтому автор никогда не приводил пример того, о чем он говорил, и онлайн-поиски ничего не вытянули в этом направлении.

Iнадо предположить, что мы говорим о что-то , которое выглядит так:

public class Dog implements Serializable
{
    // ...

    public Dog deepClone()
    {
        Dog dogClone = null;
        try
        {
            FileOutputStream fout = new FileOutputStream("mydog.dat");
            ObjectOutputStream oos = new ObjectOutputStream(fout);
            oos.writeObject(this);
            oos.close();

            FileInputStream fin = new FileInputStream("mydog.dat");
            ObjectInputStream ois = new ObjectInputStream(fin);
            dogClone = (Dog)ois.readObject();
            ois.close();

            return dogClone;
        }
        catch(Exception e)
        { 
            // Blah
        }
    }

При условии, что я могу быть немного отключен (плюс или минус несколько строк кода), это общепринятая практика глубокого клонирования объекта? Есть ли какие-либо подводные камни или предостережения в этом методе?

Существуют ли проблемы с синхронизацией / параллелизмом / безопасностью потоков?

Потому что, если это лучший способ глубокого клонирования объектов, я собираюсь использовать его религиозно .

1 Ответ

2 голосов
/ 25 сентября 2011

Это одна из распространенных практик глубокого клонирования.Недостатки:

  1. Обычно сериализация / десериализация выполняется медленно.Пользовательское клонирование выполняется быстрее.

  2. Он клонирует только сериализуемые объекты, очевидно

  3. Трудно узнать, что вы сериализуете.Если ваша собака имеет восходящий указатель на какую-то большую структуру (стаю собак), клонирование собаки может клонировать сотню других собак, если вы не будете обращать на это внимания.Ручной клон Dog, вероятно, просто игнорирует ссылку на стаю, создавая новый отдельный объект собаки с такими же свойствами, возможно, ссылаясь на такую ​​же стаю собак, но не клонируя стаю.

Безопасность потоков не отличается от ручного клонирования.Скорее всего, свойства будут последовательно считываться из исходного объекта сериализатором, и если вы не позаботитесь о безопасности потоков, вы можете клонировать собаку, которая частично изменилась во время клонирования.

Так что я бы сказал, что, вероятно, не рекомендуется использовать это все время.Для действительно простого объекта создание простого ручного клонирующего / копирующего конструктора просто и будет работать намного лучше.И для графа сложных объектов вы можете обнаружить, что это рискует клонировать вещи, которые вы не собирались.Поэтому, хотя это полезно, его следует использовать с осторожностью.

Кстати, в вашем примере я бы использовал поток памяти, а не поток файлов.

...