Só para tornar mais claro. Eu escrevi um programa com base na sua questão e o rodei.
import java.util.*;
import java.io.*;
class ClassePai {
ClassePai(){ System.out.println("ClassePai"); }
}
class ClasseFilha extends ClassePai implements Serializable{
ClasseFilha(){System.out.println("ClasseFilha");}
}
class TesteSerializacao {
public static void main(String[] args) throws Exception {
System.out.println ("Serializando um objeto da classe ClasseFilha...");
ObjectOutputStream oos = new ObjectOutputStream (new FileOutputStream ("teste.bin"));
oos.writeObject (new ClasseFilha());
oos.close();
System.out.println ("Carregando um objeto serializado da classe ClasseFilha...");
ObjectInputStream ois = new ObjectInputStream (new FileInputStream ("teste.bin"));
Object obj = ois.readObject ();
ois.close();
System.out.println ("A classe do objeto carregado é " + obj.getClass().getName());
}
}
Rodando esse programa, obtive o seguinte resultado:
C>c:\jdk1.6.0\bin\java -cp . TesteSerializacao
Serializando um objeto da classe ClasseFilha...
ClassePai
ClasseFilha
Carregando um objeto serializado da classe ClasseFilha...
ClassePai
A classe do objeto carregado é ClasseFilha
De fato, ao carregarmos o tal objeto, foi impresso "ClassePai". O que é mais estranho é o que vai ocorrer agora. Vou modificar o programa para que ambas as classes implementem Serializable.
import java.util.*;
import java.io.*;
class ClassePai implements Serializable {
public ClassePai() {
System.out.println("ClassePai");
}
}
class ClasseFilha extends ClassePai implements Serializable{
public ClasseFilha() {
System.out.println("ClasseFilha");
}
}
class TesteSerializacao {
public static void main(String[] args) throws Exception {
System.out.println ("Serializando um objeto da classe ClasseFilha...");
ObjectOutputStream oos = new ObjectOutputStream (new FileOutputStream ("teste.bin"));
oos.writeObject (new ClasseFilha());
oos.close();
System.out.println ("Carregando um objeto serializado da classe ClasseFilha...");
ObjectInputStream ois = new ObjectInputStream (new FileInputStream ("teste.bin"));
Object obj = ois.readObject ();
ois.close();
System.out.println ("A classe do objeto carregado é " + obj.getClass().getName());
}
}
A saída do programa é:
Serializando um objeto da classe ClasseFilha...
ClassePai
ClasseFilha
Carregando um objeto serializado da classe ClasseFilha...
A classe do objeto carregado é ClasseFilha
Ou seja, o carregamento do tal objeto NÃO CHAMOU os construtores das classes ClassePai e ClasseFilha. Estranho, não?
A idéia é a seguinte:
- Quando carregamos um objeto a partir de sua versão serializada (com ObjectInputStream), a idéia não é chamar os construtores da classe ou das classes-base se forem Serializable, mas sim simplesmente reconstruir os atributos da classe. Estranho, não?
No seu exemplo, a classe era Serializable (portanto o construtor definido por ela não é chamado, em vez disso só os atributos foram reconstruídos), mas a classe-base (ClassePai) não era Serializable, então o seu construtor foi chamado para fazer alguma coisa que fosse necessária.
No exemplo que dei (em que ambas as classes são Serializable), então nem o construtor nem o construtor da classe-base foram chamados. Esquisito mas é assim.
Eu também não sabia que as coisas funcionavam assim, mas ainda bem que isso não cai em provas de certificação. Realmente é bem sinistro mesmo.
Muito pelo contrário; é só o construtor que não é chamado, e sim o objeto é remontado a partir de seus atributos. (No seu exemplo ambas as classes não têm atributos, mas você pode inserir atributos nelas - variáveis de instância - e veja que os objetos são corretamente reconstruídos.)