Back-End

3 ago, 2010

Entendendo serialização em Java

Publicidade

Olá, Pessoal!

É bastante comum alguns programadores ficarem com algumas perguntas como para que serve a serialização, o que é, como entender a essência desse recurso. Veremos no artigo de hoje uma explicação sobre o processo de serialização. 

Let’s GO…

A serialização resume-se em salvar, gravar, capturar o estado de um objeto. Ou seja, tenho um objeto de uma classe e quero salvar seu estado: uso
serialização pois, quando quiser usá-lo com seu último estado gravado, é somente des-serializá-lo.

Mas por que usar isso?

Usar
serialização permite que você crie o objeto ou uma variável
de instância de uma classe e grave em um arquivo para, futuramente, utilizar esse objeto/variável
com seu estado que foi gravado.

  • Lembre-se: quando o
    construtor é executado, os valores são perdidos, objeto = null, e os tipos primitivos recebem seus valores padrões.

Com
a serialização, um
objeto ou uma variável de instância tem o valor gravado (em um arquivo),
armazenado e futuramente posso obter esse valor através da des-serialização.

Um exemplo básico do código de serialização
e des-serialização de objetos:

import java.io.*;
 class Cat implements Serializable{} //1
class SerializeCat{
     public static void main(String args[]){
   Cat c = new Cat(); //criando o objeto
    //aqui vou serializar meu objeto da class cat
  try{
FileOutputStream fo = new FileOutputStream("test.ser");
ObjectOutputStream oo = new ObjectOutputStream(fo);
   oo.writeObject(c); // serializo objeto cat
    oo.close();
System.out.println("Class Cat - object serializado com sucesso");  }
  catch(Exception e){e.printStackTrace();}        
//des-serializo o objeto
try{
    FileInputStream fi = new FileInputStream("test.ser");
    ObjectInputStream oi = new ObjectInputStream(fi);
    c =(Cat) oi.readObject();
    oi.close();
System.out.println("agora ele foi des-serializado com sucesso");
}catch(Exception e){e.printStackTrace();}          }}
  • Criei uma class Cat que implementa a interface (marcadora) Serializable; essa interface não possui nenhum método a ser implementado.
  • ObjectxxxStream: é a classe que possui o método mágico de serialização write e read
    – Object.
  • writeObject: serializa o objeto depois escreve o objeto já
    serializado no arquivo.

Herança  e Serialização

Quando temos uma subclasse que herda tudo da sua classe pai,
o que acontece com serialização? Nesse caso, temos uma pequena regra a seguir:
se sua classe PAI, implementar Serializable, então a sua subclasse implicitamente
já faz Serializable.

Mas se sua classe pai não implementa Serializable e sua subclasse implementa, então, apenas os objetos da sua subclasse, vamos serializar
o da classe pai, que infelizmente terá seus valores iniciais ou padrão. Um exemplo
prático:

class Animal{}
class Dog extends Animal implements Serializable{}

No exemplo anterior, apenas Dog é serializado.

 Um exemplo mais prático:

class Foo implements Serializable{
int num = 3;
void Num(){num=10;}}

Quando a classe Foo for serializada e rodar o método Num(), ela vai
gravar o valor 10 para a variável int que criamos e, quando for des-serializada,
é ideal que ela mantenha esse valor.

Tenha em mente

Em um objeto des-serializado, nós

  • não queremos que a inicialização normal rode.
  • não queremos que os construtores rodem.
  • não queremos que os valores explicitamente declarados sejam
    atribuídos.

Na verdade, queremos apenas
um retorno do estado que foi gravado, serializado.

Serialização não está para static

Quando
se diz “serialização não está para
static”
, isso não quer dizer que seu código não vai compilar ou vai lançar
alguma exceção caso você tente serializar uma variável static. Simplesmente diz que não é possível gravar o estado de uma
variável static. Mas por quê?

Como a variável static não tem objetos, ela
pertence à classe, ao contrário das  variáveis de instância, que pertencem a
um objeto. Sabemos que no static o
valor da variável é compartilhado para todos, então se serializo 10, mas depois altero
o valor para 20, então na
des-serializacao vai retornar 20 – já que não temos instância nenhuma do static ele
vai trazer o último valor.

Algumas regras importantes

  • modificador Transient: ignora o objeto ou variável durante a
    serialização, isso aqui não vai serializado;
  • caso o
    arquivo especificado na des-serialização não exista, ele não é des-serializado e
    então acontece a serialização, mas uma exceção é lançada por o arquivo não
    existir;
  • as
    classes precisam implementar a interface Serializable para que os seus objetos possam
    ser serializados;
  • se a
    superclasse implementar Serializable, então as suas subclasses também a
    implementam automaticamente;
  • se a superclasse não implementar Serializable,
    então quando um objeto da subclasse for des-serializado o construtor da
    superclasse será executado;
  • se sua classe serializable tiver referência para outra classe que
    não é serializable, uma exceção ocorre em tempo de exceção;
  • posso serializar apenas objeto (autoboxing funciona primitivo
    >> objeto);
  • ObjectInputStream a lê e
    des-serializa;
  • ObjectOutputStream a escreve e
    serializa.

Essas são algumas regras e funcionamento de
Serialização, espero ter tirado algumas dúvidas.

Um
abraço a todos! E até a próxima!