Questão sobre serialização

4 respostas
jason_bourne

Pessoal,

Tenho essa questão:

public class ClassePai {
	ClassePai(){ System.out.println("ClassePai"); }
}
public class ClasseFilha extends ClassePai implements Serializable{
	ClasseFilha(){System.out.println("ClasseFilha");}
}

O q sera printado se o objeto for deserializado?

Bom…tenho duas perguntas sobre essa questão:
-Um objeto serializado é um objeto gravado em disco?
-A resposta pra questão é ClassePai. Então se eu deserializo a ClasseFilha, ele não grava mais no disco e portanto o objeto não existe mais?

4 Respostas

T

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.)

victorwss

Pode ser, mas nem sempre é. As vezes é uma seqüência de bits viajando em um cabo de rede. :slight_smile:

Não!
Serializar = escrever um fluxo de bytes que corresponde a um objeto.
Desserializar = ler um fluxo de bytes que corresponde a um objeto.

Observe que não há nada que diga que o objeto original é destruído quando é serializado e nem nada que diga que o fluxo de bytes é destruído quando é desserializado.

[/quote]

jason_bourne

Se não cai na prova scjp 5…pq então no software de treino do livro preparatório pra certificação da alta books tem essa questão?

LPJava

serialização cai na prova sim, na minha caiu one questao apenas mais caiu, perguntado o resultado… ele serializou dois objetos e queria saber qual era o estado do objeto apos a deserializacao.

É so ficar atento as regras e praticar bastante serializacao pq vc tem que matar a questao de imediato pq sao questoes que tem mais codigo para ler e vc deve ler cada linha va que tenha uma pegadinha no meio nao deixando o codigo nem compilar…

A serialização é um processo de vc salvar os dados de um objeto. Normalmente vc grava em arquivos. Isso acontece pq quando os construtores rodam as variaveis de instancias recebem seus valores padroes, ou seja, é como vc reiniciar o seu sistema operacional tudo eh apagado e com serialização vc pode manter o ultimo estado de um objeto antes dele “morrer”.

flw!

Criado 29 de setembro de 2008
Ultima resposta 30 de set. de 2008
Respostas 4
Participantes 4