Questão de certificação

8 respostas
joaoorso

Que coisa em … essa história da certificação dá o que falar :shock:
Tenho uma dúvida aqui sobre Serealização… o código é :

import java.io.*;
 
 public class SuperNotSerial {
    public static void main(String args[]) {
        Dog d = new Dog(35,"fido");
      System.out.println("before: "+d.name+" "+d.weight);
      try {
         FileOutputStream fs = new FileOutputStream("testser.ser");
       ObjectOutputStream os = new ObjectOutputStream(fs);
       os.writeObject(d);
       os.close();
      } catch(Exception e) { e.printStackTrace(); }    
      try {
         FileInputStream fis = new FileInputStream("testser.ser");
       ObjectInputStream ois = new ObjectInputStream(fis);
       d = (Dog) ois.readObject();
       ois.close();      
      } catch (Exception e) { e.printStackTrace(); }
      System.out.println("after: "+d.name+" "+d.weight);    
    }
 }   
    
 class Dog extends Animal implements Serializable {
    String name;
    Dog(int w,String n) {
     weight = w;
     name = n;     
    }        
 }
    
 class Animal {
    int weight = 40;
 }

O retorno desse código é :
before: fido 35
after: fido 40

Mas por que weight recebeu o valor da classe pai depois da Serealização ?
Onde foi parar o valor original ?
Onde estão os construtores das classes ? :?: :?: :?:

8 Respostas

Luca

Olá

Fui ler o último link que peguei no google e passei para você e vi que não explica exatamente o motivo da sua dúvida tal como imaginei. Por este motivo apaguei a mensagem

O que chama a atenção no seu caso é que o campo weight faz parte de uma classe não marcada como serializable. Na reconstrução do objeto, este campo não vem da serialização (porque não foi serializado). Ficou claro?

  1. Veja o arquivo teste.ser
  2. Inclua implements Serializable na classe Animal, recompile e execute
  3. Veja o arquivo teste.ser de novo e verifique que agora tem o campo weight

[]s
Luca (que tentou mostrar onde estudar e se deu mal)

joaoorso

:oops: Sabe como é … meu ingles não é lá aquelas coisas :oops:

T

Cuidado com a grafia das palavras - é “serialização”, não “serealização” - eu lembro de um humorístico que mostrava um “Cereal Killer”, acho que era um assassino fantasiado como o tigre Tony (das embalagens dos Sucrilhos Kellogg’s). O Google até corrige mais ou menos seu português, mas se você passar as palavras corretas ele acha as coisas melhor.

Luca

Olá

Apaguei a minha primeira resposta porque o link que passei não explicava o que eu queria que explicasse

[]s
Luca

joaoorso

Então o atributo weight não é retornado por que não foi serealizado ?
Ainda tá meio confuso … :?

Quando que o constor da classe pai foi chamado para atribuir o valor 40 a weight ?

obrigado :thumbup:

Luca

Olá

Preste atenção sobre o que o thingol escreveu

No momento que o novo objeto d foi construído a partir da leitura do arquivo teste.ser. Na construção deste objeto, foi chamado o construtor de Animal como acontece na construção de qualquer objeto. Isto não ocorreria se o objeto Dog viesse completo de teste.ser

[]s
Luca

T

Tomei a liberdade de pegar seu programa e mostrar um que é exatamente equivalente a ele (o compilador geraria o mesmo código).
Pus alguns comentários.

Puxa vida, nunca tinha percebido esse tipo de coisa (ou seja, quais são as conseqüências de herdar de uma classe que não implementa Serializable). Podem realmente acontecer coisas inesperadas.

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;

public class SuperNotSerial {
	public static void main(String args[]) {
		Dog d = new Dog(35, "fido");
		System.out.println("before: " + d.name + " " + d.weight);
		try {
			FileOutputStream fs = new FileOutputStream("testser.ser");
			ObjectOutputStream os = new ObjectOutputStream(fs);
			os.writeObject(d);
			os.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
		try {
			FileInputStream fis = new FileInputStream("testser.ser");
			ObjectInputStream ois = new ObjectInputStream(fis);
			
			// Note que d = (Dog) ois.readObject() se comporta mais ou menos como se fosse:
			// d = new Dog(); // neste ponto, weight = 40, como você deve saber 
			// d.name = Valor serializado de name (mencionado na declaração)
			// Não é executado d.weight = 35, porque esse campo (weight) não é mencionado
			// em uma classe que implementa Serializable. Nesse caso, é declarado
			// apenas em Animal, que não implementa Serializable.
			// Se você remover os comentários abaixo na declaração da class Animal, 
			// então o valor de d será (name = Fido, weight = 35) como você estava
			// supondo que fosse.
			d = (Dog) ois.readObject();
			
			ois.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
		System.out.println("after: " + d.name + " " + d.weight);
	}
}

class Dog extends Animal implements Serializable {
	String name; // isto foi serializado
	Dog () {
		super();
	}
	Dog(int w, String n) {
		super();
		weight = w;
		name = n;
	}
}

class Animal /* implements Serializable */ {
	int weight;
	public Animal () {
		weight = 40;
	}
}
joaoorso

Obrigado pela ajuda. Agora ficou claro :idea:
Só recaptulando …

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;

public class SuperNotSerial {
	public static void main(String args[]) {
		Dog d = new Dog(35, "fido");
		System.out.println("before: " + d.name + " " + d.weight);
		try {
			FileOutputStream fs = new FileOutputStream("testser.ser");
			ObjectOutputStream os = new ObjectOutputStream(fs);
			os.writeObject(d);
			os.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
		try {
			FileInputStream fis = new FileInputStream("testser.ser");
			ObjectInputStream ois = new ObjectInputStream(fis);			
			d = (Dog) ois.readObject();
                        /*
                         Nesse ponto do código ...
                         o atributo name foi deserializado e atribuido a d
                         o atributo weight foi recriado através dos construtores                                                  
                        */
			
			ois.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
		System.out.println("after: " + d.name + " " + d.weight);
	}
}

class Dog extends Animal implements Serializable {
	String name; 
	Dog () {//  esse seria o construtor default,
		super(); //que é gerado pelo proprio java, por isso ele foi omitido.                
	}
	Dog(int w, String n) {
		super();
		weight = w;
		name = n;
	}
}

class Animal {//implements Serializable  
     // Acrescentandoo comentário acima, a classe Animal,  ela torna-se serializavel,
    //Assim ambos os atributos de Dog seriam serializados e o retorno seria :
    //before: fido 35
    //after: fido 35

    
	int weight; // Esse atributo não foi (será) serializado pois a classe não faz
                    // implements em Serializable.
	public Animal () {
		weight = 40;
	}
}

Valeu …

Criado 26 de maio de 2008
Ultima resposta 26 de mai. de 2008
Respostas 8
Participantes 3