Модераторы: LSD, AntonSaburov
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Вопрос по сериализации, Мутатор не меняет значение поля 
V
    Опции темы
Artiom18
Дата 10.12.2013, 18:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 32
Регистрация: 9.3.2008

Репутация: нет
Всего: нет



Возник такой вопрос.
Есть класс
Код

public class Line implements java.io.Serializable {
    private Point point1;
    private Point point2;
    private int index;

    public Line() {
        System.out.println("Constructing empty line");
    }

    Line(Point p1, Point p2, int index) {
        System.out.println("Constructing line: " + index);
        this.point1 = p1;
        this.point2 = p2;
        this.index = index;
    }

    public int getIndex() {
        return index;
    }

    public void setIndex(int newIndex) {
        index = newIndex;
    }

    public void printInfo() {
        System.out.println("Line: " + index);
        System.out.println("\tObject reference: " + super.toString());
        System.out.println("\tfrom point " + point1);
        System.out.println("\tto point " + point2);
    }
}

И мы его сериализуем, а потом восстанавливаем:
Код

public class SomeReferencesSerialization {
    public static void main(String[] args) {
        Point p1 = new Point(1.0, 1.0);
        Point p2 = new Point(2.0, 2.0);
        Point p3 = new Point(3.0, 3.0);
        Line line1 = new Line(p1, p2, 1);
        Line line2 = new Line(p2, p3, 2);
        line1.printInfo();
        line2.printInfo();
        String fileName = "file.bin";
        try {
            FileOutputStream os = new FileOutputStream(fileName);
            ObjectOutputStream oos = new ObjectOutputStream(os);

            oos.writeObject(line1);
            oos.writeObject(line2);

            line1.setIndex(11); // #1
            line2.setIndex(22); // #2

            System.out.println("After changing index");
            line1.printInfo();
            line2.printInfo();
            
            oos.writeObject(line1);
            oos.writeObject(line2);

            oos.close();
            os.close();
            System.out.println("Read objects:");
            FileInputStream is = new FileInputStream(fileName);
            ObjectInputStream ois = new ObjectInputStream(is);
            while (is.available() > 0) {
                Line line = (Line) ois.readObject();
                line.printInfo();
            }
            ois.close();
            is.close();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

В результате, несмотря на то, что после строк #1 и #2 значения полей index меняются, после десериализации они вновь равны "1" и "2" для line1 и line2 соответственно (как при изначальном создании инстансов).
Вопрос, почему это происходит?

Это сообщение отредактировал(а) Artiom18 - 10.12.2013, 19:00
PM MAIL   Вверх
LSD
Дата 11.12.2013, 10:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Leprechaun Software Developer
****


Профиль
Группа: Модератор
Сообщений: 15718
Регистрация: 24.3.2004
Где: Dublin

Репутация: 210
Всего: 538



Цитата(Artiom18 @  10.12.2013,  19:59 Найти цитируемый пост)
Вопрос, почему это происходит?

Потому что:
Цитата(Artiom18 @  10.12.2013,  19:59 Найти цитируемый пост)
И мы его сериализуем, а потом восстанавливаем:




--------------------
Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don't take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don't read it.
PM MAIL WWW   Вверх
Artiom18
Дата 11.12.2013, 10:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 32
Регистрация: 9.3.2008

Репутация: нет
Всего: нет



LSD,  поясните, пожалуйста, тогда процесс.
Мы создаем  объект с index = 1.
Код

Line line1 = new Line(p1, p2, 1);

Первый раз мы записываем в файл его:
Код

oos.writeObject(line1);

Код

Затем:
line1.setIndex(11);

Здесь мы теоретически изменили index на 11. Это подтверждает вывод
Код

line1.printInfo();

Я не могу понять, когда мы опять получаем index = 1. При второй записи в файл или уже при десериализации? И на основании чего.
P.S. И как тогда можно сохранить измененное поле?

Это сообщение отредактировал(а) Artiom18 - 11.12.2013, 10:59
PM MAIL   Вверх
Artiom18
Дата 11.12.2013, 11:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 32
Регистрация: 9.3.2008

Репутация: нет
Всего: нет



Кажется понял, в чем дело. Суть в том, что если не закрыть поток ObjectOutputStream перед вторым вызовом, то запишется не новое состояние, а объект из кэша потока.
PM MAIL   Вверх
LSD
Дата 11.12.2013, 11:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Leprechaun Software Developer
****


Профиль
Группа: Модератор
Сообщений: 15718
Регистрация: 24.3.2004
Где: Dublin

Репутация: 210
Всего: 538



ObjectOutputStream кеширует уже сериализованные объекты в IdentityHashMap. Это деляется для того, чтобы корректно сериализовывать деревья объектов, т.е. если есть два объекта A ссылается на B и B ссылается на A. И мы сериализуем вначале A, потом B, то при десериализации мы получим 2 объекта с взаимными ссылками, а не 4.
В твоем случае это приводит к тому, что второй раз объекты не сериализуются, а просто записывается ссылка на ранее сериализованный объект. Метод reset() решает проблему.
Код

        Line line1 = new Line(1);
        Line line2 = new Line(2);
        line1.printInfo();
        line2.printInfo();

        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(bos);
        oos.writeObject(line1);
        oos.writeObject(line2);
        oos.reset();
        line1.setIndex(11); // #1
        line2.setIndex(22); // #2
        System.out.println("After changing index");
        line1.printInfo();
        line2.printInfo();

        oos.writeObject(line1);
        oos.writeObject(line2);
        oos.close();


        System.out.println("Read objects:");
        ByteArrayInputStream bin = new ByteArrayInputStream(bos.toByteArray());
        ObjectInputStream ois = new ObjectInputStream(bin);
        while (bin.available() > 0) {
            Line line = (Line) ois.readObject();
            line.printInfo();
        }
        ois.close();



--------------------
Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don't take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don't read it.
PM MAIL WWW   Вверх
Artiom18
Дата 11.12.2013, 11:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 32
Регистрация: 9.3.2008

Репутация: нет
Всего: нет



LSD, спасибо за развернутый ответ. 
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Java"
LSD   AntonSaburov
powerOn   tux
javastic
  • Прежде, чем задать вопрос, прочтите это!
  • Книги по Java собираются здесь.
  • Документация и ресурсы по Java находятся здесь.
  • Используйте теги [code=java][/code] для подсветки кода. Используйтe чекбокс "транслит", если у Вас нет русских шрифтов.
  • Помечайте свой вопрос как решённый, если на него получен ответ. Ссылка "Пометить как решённый" находится над первым постом.
  • Действия модераторов можно обсудить здесь.
  • FAQ раздела лежит здесь.

Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, tux, javastic.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Java: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0552 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.