Pregunta

Tengo una jerarquía de clases bastante simple:

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);
    }
}

Cuando se crea una nueva instancia de la LongIdDropdownOption, que hace implementar Serializable; serializarlo; y luego deserializar inmediatamente - entonces el objeto deserializado tiene sus dos campos establecidos en nulo:

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 */
}

Cuando hago la clase base implementar Serializable, el código comienza a funcionar correctamente. Mi pregunta es ... ¿por qué?

¿Fue útil?

Solución

Como se ha descrito aquí - http://java.sun.com/developer/technicalArticles/ ALT / serialización "una razón común para anular readObject y writeObject es serializar los datos de una superclase que no es Serializable en sí".

El estado que usted piensa que tiene en su instancia subclase no es realmente visible para la serialización, ya que no va a través de su API o la reflexión. En lo que se refiere a proceso de serialización del estado pertenece a la super clase que no implementa Serializable. Aquí es donde se pierde.

Aquí hay un enlace a un objeto Java La serialización especificación que debe explicarlo: http://download.oracle.com/javase/6 /docs/platform/serialization/spec/serialTOC.html

Otros consejos

Debido a que ya que sólo los instrumentos de la clase infantil Serializable, sólo sus campos serán serializados por la JVM. La JVM no ve a los padres miembros como miembros de la clase hija, ya que utiliza la reflexión para enumerar los campos de clase.

A partir de Java Docs Aquí

Si la clase A no implementa Serializable, pero una subclase B implementa Serializable, se pueden serializar los campos de la clase A cuando se serializa B?

Sólo los campos de objetos serializables se escriben y restaurado. El objeto puede ser restaurado sólo si tiene un constructor sin argumentos que inicializar los campos de supertipos no serializable. Si la subclase tiene acceso al estado de la superclase puede aplicar writeObject y readObject para guardar y restaurar ese estado.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top