Serialización y herencia de objetos Java


Digamos que tienes estas dos clases, Foo y Bar donde Bar extiende Foo e implementa Serializable

class Foo {

public String name;

public Foo() {
    this.name = "Default";
}

public Foo(String name) {
    this.name = name;
}
}

class Bar extends Foo implements java.io.Serializable {

public int id;

public Bar(String name, int id) {
    super(name);
    this.id = id;
}
}

Observe que Foo no implementa Serializable. Entonces, ¿qué sucede cuando bar es serializado?

    public static void main(String[] args) throws Exception {

    FileOutputStream fStream=new FileOutputStream("objects.dat");
    ObjectOutputStream oStream=new ObjectOutputStream(fStream);
    Bar bar=new Bar("myName",21);
    oStream.writeObject(bar);

    FileInputStream ifstream = new FileInputStream("objects.dat");
    ObjectInputStream istream = new ObjectInputStream(ifstream);
    Bar bar1 = (Bar) istream.readObject();
    System.out.println(bar1.name + "   " + bar1.id);

} 

Imprime "Default 21". La pregunta es, ¿por qué se llama al constructor predeterminado cuando la clase no está serializada?

Author: Sleiman Jneidi, 2011-12-26

3 answers

Serializable es solo una "interfaz de marcador" para una clase dada.

Pero esa clase debe adherirse a ciertas reglas:

Http://docs.oracle.com/javase/1.5.0/docs/api/java/io/Serializable.html

Para permitir que subtipos de clases no serializables sean serializados, el subtipo puede asumir la responsabilidad de salvar y restaurar el estado del paquete público, protegido y (si es accesible) del supertipo campo. El subtipo puede asumir esta responsabilidad solo si la clase se extiende tiene un constructor no-arg accesible para inicializar el el estado de la clase. Es un error declarar una clase serializable si esto no es el caso.

Para responder @Sleiman Jneidi pregunta hecha en el comentario, en la documentación de oracle mencionada anteriormente, su claramente mencionado

Durante la deserialización, los campos de las clases no serializables se inicializarán usando el constructor no-arg público o protegido de la clase. Un constructor no-arg debe ser accesible para la subclase que es serializable. Los campos de las subclases serializables serán restaurados desde la corriente.

Por lo tanto, el constructor predeterminado no-arg de la clase Foo llamado of, resultó en la inicialización.

 20
Author: paulsm4,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-02-14 14:42:52

Puede ser que el defaultWriteObject solo pueda escribir los campos no estáticos y no transitorios de la clase actual. Una vez que la superclase no implementa la interfaz serializable, los campos de la superclase no pueden ser serializados en la secuencia.

 4
Author: andy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-08-07 13:13:46

En realidad cuando leerá el objeto de la clase padre, ya que no es serializar en absoluto.. así que para las cosas no serializar otra vez JVM ir a través del mismo proceso como se utiliza para ir cuando creamos el nuevo objeto usando nueva palabra clave.

 0
Author: Vishesh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-12-25 05:48:09