Serialização

17 respostas
anderson.bonavides

E ai turma revisando a parte de serialização me deparei com as seguintes duvidas:
Quando é que serialização lança exceção?
Outra dúvida em relação a serialização é quando eu preciso subscrever o método:

private void writeObject(ObjectOutputStream os){ try{ os.defaultWriteObject(); }catch(Exception e) }
Fico grato se alguêm poder me mostrar algum exêmplo e me explicase sobre o assunto.

17 Respostas

Raff

creio que ela lançara uma exeção quando não conseguir fazer uma chamada ao S.o (não tenho certeza disso !)

Raff

você sobrescreve o metodo writeObject() quando você quiser fazer a serialização manualmente, ou quando você tem um Objeto que por algum motivo ele não seja Serializable, então você o marca como transient e serializa um valor dele para não perder !!!

anderson.bonavides
Raff:
creio que ela lançara uma exeção quando não conseguir fazer uma chamada ao S.o (não tenho certeza disso !)

Descobri o mótivo para lançar uma exceção.

class Pai{}
class Filho extends Pai implements Serializable{

	Pai p = new Pai();

	public static void main(String[] args) {
		
		Filho f = new Filho();
		try {
			FileOutputStream fs = new FileOutputStream("Filho.doc");
			ObjectOutputStream os = new ObjectOutputStream(fs);
			os.writeObject(f);
			os.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

Para tentar serealizar um filho o pai deve ser serealizado o que não ocorre gerando uma exceção.

Raff

não cara… não é bem assim. A serialização faz com que o construtor da classe marcado com Serializable não “rode” este caso seu ai da erro por que a classe Filho tem - um (has - as) Pai, e o Pai não é serializable, sendo assim causa um Exception !!

import java.io.*;
public class Pai {
}
public class Filho extends Pai implements Serializable{

public static void main(String... rafa){
       Filho fi = new Filho();
try{       
ObjectOuputStream st = new ObjectOutputStream(new FileOutputStream("Filho.ser'));
st.writeObject(fi);//isso não vai dar erro não !!!!!!!
catch(IOException e){}
}
}
Raff

anderson, na verdade nem o seu codigo vai lançar um Exception, você fez os teste ?

anderson.bonavides

To vendo que vc não colocou o e.printStackTrace() na sua clausula catch(). Coloca ai vc confere.

E só confirmando. Caso vc nescessite serealizar um filho e o filho nescessite serealizar um pai e o pai não é serealizado isso causa exception. Para solucionar o problema a instância da classe Pai deve ser transient.

Procura lá no teu livro da kathy que fala. Se for em português e for a segunda edição revisada eu te mostro.

Raff

foi mal cara verdade você tem toda razão :oops:

anderson.bonavides

:wink:
Esses debates são legais faz aprendermos.

Raff

tu tem razão !!!

sergiotaborda

Não. A solução é que o Pai deve ser Serializable. Uma hierarquia onde os filhos são serializáveis e os pais não é um hierarquia errada. Repare: se o pai não é serializável como o filho pode ser ? (as propriedades do pai passam para o filho) .

Vc precisa escreve o método write (e o read) quando a serialização do objeto não é normal.
Por exemplo, vc pode incluir compressão zip ou vc pode usar objetos diferentes para a serialização.
Um exemplo é uma serialização de um objeto que contenha um Calendar. Vc pode querer apenas usar um Date ou até um long. A escrita dos métodos write e read permite ajustes finos sobre como o objeto é serializado. Isso é especialmente importante em objeto “grandes” jeitos para navegar na rede ( os Transfer Objects)

anderson.bonavides

sergiotaborda:

Não. A solução é que o Pai deve ser Serializable. Uma hierarquia onde os filhos são serializáveis e os pais não é um hierarquia errada. Repare: se o pai não é serializável como o filho pode ser ? (as propriedades do pai passam para o filho) .

Vc precisa escreve o método write (e o read) quando a serialização do objeto não é normal.
Por exemplo, vc pode incluir compressão zip ou vc pode usar objetos diferentes para a serialização.
Um exemplo é uma serialização de um objeto que contenha um Calendar. Vc pode querer apenas usar um Date ou até um long. A escrita dos métodos write e read permite ajustes finos sobre como o objeto é serializado. Isso é especialmente importante em objeto “grandes” jeitos para navegar na rede ( os Transfer Objects)

Desculpe mas discordo com sua primeira afirmação. Não é obrigado para o filho ser seralizado apenas se o pai for. Classes que são serializadas não rodam seus construtores. Classes que não são serealizadas, rodam seus construtores. Se vc não conhece uma classe Pai e não tem certeza que ela é serealizada é só marcar como transient assim ela não será. A kathy fala isso em seu livro.

D

Sim, é só marcar como transient… mas tem algum sentido isso??? Sendo que você uma HERANÇA???

É melhor aprender antes o conceito… depois as pegadinhas de certificação…

anderson.bonavides

du123:
Sim, é só marcar como transient… mas tem algum sentido isso??? Sendo que você uma HERANÇA???

É melhor aprender antes o conceito… depois as pegadinhas de certificação…

O conceito ja to sabendo. Isso era apenas um detalhe que não tava sabendo e queria ver um exemplo.

Sami_Koivu

Olá,

:arrow: O código do Raff (depois de corrigir os erros de sintaxe) roda sem exceções. (Mas é verdade que ter um bloco catch vazio é feio :) )

:arrow: O motivo do código:

class Pai{}
class Filho extends Pai implements Serializable{

	Pai p = new Pai();

	public static void main(String[] args) {
		
		Filho f = new Filho();
		try {
			FileOutputStream fs = new FileOutputStream("Filho.doc");
			ObjectOutputStream os = new ObjectOutputStream(fs);
			os.writeObject(f);
			os.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

lançar uma exceção deve-se ao classe em questão ter um campo onde está guardado um objeto não-serializavel (o objeto da classe Pai). O fato desse objeto ser da classe Pai que é a classe pai da outra classe não importa.

Você poderia trocar a linha

Pai p = new Pai();

para

Object o = new Object();

E daria a mesma exceção.

Em principio concordo com a lógica do Sergio, mas ao meu ver Java não força essa lógica. Veja o caso da classe Object que é o pai de todas as outras classe e que não é Serializavel.

[marketing]A nova versão do reJ terá um recurso para visualizar e modificar arquivos de objetos serializados. A funcionalidade está praticamente pronta, só falta eu conseguir um pouquinho folego do trabalho para finalizar as coisas.[/marketing]

anderson.bonavides
Sami Koivu:
Olá,

:arrow: O código do Raff (depois de corrigir os erros de sintaxe) roda sem exceções. (Mas é verdade que ter um bloco catch vazio é feio :) )

:arrow: O motivo do código:

class Pai{}
class Filho extends Pai implements Serializable{

	Pai p = new Pai();

	public static void main(String[] args) {
		
		Filho f = new Filho();
		try {
			FileOutputStream fs = new FileOutputStream("Filho.doc");
			ObjectOutputStream os = new ObjectOutputStream(fs);
			os.writeObject(f);
			os.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

lançar uma exceção deve-se ao classe em questão ter um campo onde está guardado um objeto não-serializavel (o objeto da classe Pai). O fato desse objeto ser da classe Pai que é a classe pai da outra classe não importa.

Você poderia trocar a linha

Pai p = new Pai();

para

Object o = new Object();

E daria a mesma exceção.

Em principio concordo com a lógica do Sergio, mas ao meu ver Java não força essa lógica. Veja o caso da classe Object que é o pai de todas as outras classe e que não é Serializavel.

[marketing]A nova versão do reJ terá um recurso para visualizar e modificar arquivos de objetos serializados. A funcionalidade está praticamente pronta, só falta eu conseguir um pouquinho folego do trabalho para finalizar as coisas.[/marketing]

Mas claro que trocando por Object vai dar exceção também. Isso se deve ao motivo de que a classe nesecissita serealizar Object e Object não é serealizavel. Esse é o ponto que quero colocar. Esse é o motivo para ser lançado a exceção. Vc pode trocar Pai por qualquer coisa que não seja serealizavel e a exceção vai ser lançada. Como já disse a kathy também trata desse assunto e isso também é um ponto importante para se saber. Vc quase sempre vai ver uma questão dessa em algum simulado como por exemplo no killer.

Deluxe

é so colocar a referencia pai
dentro do metodo static
pronto
=)
compila e roda sem problemas

anderson.bonavides

Deluxe:
é so colocar a referencia pai
dentro do metodo static
pronto
=)
compila e roda sem problemas

Legal. Mais ai a referência não vai mais pertencer a classe. E como o nosso amigo falou em cima o recurso não é valido para a prova o que torna importante saber isso também e a titulo de informação essa foi uma questão de prova.

:wink:

Criado 16 de janeiro de 2008
Ultima resposta 18 de jan. de 2008
Respostas 17
Participantes 6