Почему мои объекты не десериализованы правильно? - PullRequest
2 голосов
/ 02 декабря 2010

У меня довольно простая иерархия классов:

public class DropdownOption<T> /* does NOT implement Serializable */ {
    private T value;
    private String label;

    public DropdownOption() {
        this (null, null);
    }

    public DropdownOption(T value, String label) {
        this.value = value;
        this.label = label; 
    }

    public T getValue() {
        return value;
    }

    public void setValue(T value) {
        this.value = value;
    }

    public String getLabel() {
        return label;
    }

    public void setLabel(String label) {
        this.label = label;
    }
}

/**
 * Convenience decorator
 */
public class LongIdDropdownOption extends DropdownOption<Long> 
    implements Serializable {

    private static final long serialVersionUID = -3920989081132516015L;

    public LongIdDropdownOption() {
        super();        
    }

    public LongIdDropdownOption(Long value, String label) {
        super(value, label);
    }

    public Long getId() {
        return getValue();
    }

    public void setId(Long id) {
        super.setValue(id);
    }
}

Когда я создаю новый экземпляр LongIdDropdownOption, который действительно реализует Serializable;сериализовать его;и затем немедленно десериализовать его - тогда для десериализованного объекта оба его поля установлены в нуль:

public void testSerialization() throws Exception {
    LongIdDropdownOption option = new LongIdDropdownOption(1L, "One");         

    ByteArrayOutputStream buffer = new ByteArrayOutputStream();
    ObjectOutputStream os = new ObjectOutputStream(buffer);
    os.writeObject(option);
    os.close();

    ObjectInputStream is = new ObjectInputStream(
        new ByteArrayInputStream(buffer.toByteArray()));
    LongIdDropdownOption result = (LongIdDropdownOption) is.readObject();
    is.close();

    assertNotNull(result);        
    assertEquals("One", result.getLabel()); /** Fails, label is null */
}

Когда я заставляю базовый класс реализовать Serializable, код начинает работать правильно.Мой вопрос ... почему?

Ответы [ 3 ]

4 голосов
/ 02 декабря 2010

Из документов Java Здесь

Если класс A не реализует Serializable, но подкласс B реализует Serializable, будут ли поля класса A сериализованы при сериализации B?

Только поля сериализуемых объектов записываются и восстанавливаются. Объект может быть восстановлен, только если у него есть конструктор без аргументов, который будет инициализировать поля несериализуемых супертипов. Если у подкласса есть доступ к состоянию суперкласса, он может реализовать writeObject и readObject для сохранения и восстановления этого состояния.

4 голосов
/ 02 декабря 2010

Как описано здесь - http://java.sun.com/developer/technicalArticles/ALT/serialization "одна распространенная причина переопределения readObject и writeObject - это сериализация данных для суперкласса, который сам не является сериализуемым".

Состояние, которое, по вашему мнению, имеется в вашем подклассовом экземпляре, на самом деле не видно сериализации, поскольку оно не передается через ваш API или рефлексию. Что касается процесса сериализации, то состояние принадлежит суперклассу, который не реализует Serializable. Вот где вы его потеряете.

Вот ссылка на Спецификацию Сериализации Объекта Java, которая должна объяснить это: http://download.oracle.com/javase/6/docs/platform/serialization/spec/serialTOC.html

4 голосов
/ 02 декабря 2010

Поскольку только дочерний класс реализует Serializable, только его поля будут сериализованы JVM.JVM не видит родительские члены как члены дочернего класса, так как использует отражение для перечисления полей класса.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...