Serialização

O processo de serialização de objetos permite converter a representação de um objeto em memória para uma seqüência de bytes que pode então ser enviada para um ObjectOutputStream, que por sua vez pode estar associado a um arquivo em disco ou a uma conexão de rede, por exemplo.

Por exemplo, para serializar um objeto da classe java.util.Hashtable, armazenando seu contéudo em um arquivo em disco, a seqüência de passos é:

// criar/manipular o objeto
   Hashtable dados = new Hashtable();
   ...
// definir o nome do arquivo
   String filename = ...;
// abrir o arquivo de saída
   File file = new File(filename);
      if(!file.exists()){
	 file.createNewFile();
      }
   FileOutputStream out = new FileOutputStream(file);
// associar ao arquivo o ObjectOutputStream
   ObjectOutputStream s = new ObjectOutputStream(out);
// serializar o objeto
   s.writeObject(dados);

O processo inverso, a desserialização, permite ler essa representação de um objeto a partir de um ObjectInputStream usando o método readObject():

   FileInputStream in = new FileInputStream(file);
   ObjectInputStream s = new ObjectInputStream(in);
   dados = (Hashtable) s.readObject();

Serializable

Objetos de classes para os quais são previstas serializações e desserializações devem implementar a interface java.io.Serializable, que não define nenhum método ou campo -- é uma interface marker, servindo apenas para registrar a semântica de serialização.

A serialização de um objeto deve ser implementada pela definição de um método writeObject(), com assinatura:

 private void writeObject(java.io.ObjectOutputStream out)
     throws IOException

Tipicamente, esse método realiza qualquer preparação necessária para a serialização e invoca o método defaultWriteObject() da classe ObjectOutputStream.

A desserialização é implementada pelo método readObject() com assinatura:

 private void readObject(java.io.ObjectInputStream in)
     throws IOException, ClassNotFoundException;
 

Esse método tipicamente invoca defaultReadObject() da classe ObjectInputStream e então realiza as ações complementares àquelas realizadas em writeObject(), tais como leitura de dados adicionais e inicialização de variáveis.

Serialização é um processo transitivo, ou seja, subclasses serializáveis de classes serializáveis são automaticamente incorporadas à representação serializada do objeto raiz. Para que o processo de desserialização possa operar corretamente, todas as classes envolvidas no processo devem ter um construtor default (sem argumentos).

Externalizable

Caso deseje-se controle total sobre o processe de serialização e desserialização de objetos (ao invés de usar os métodos defaultWriteObject() e defaultReadObject()), a interface java.io.Externalizable (uma extensão de Serializable) deve ser utilizada. Essa interface define os métodos:
writeExternal
 public abstract void writeExternal(ObjectOutput out) throws IOException
	  
The object implements the writeExternal method to save its contents by calling the methods of DataOutput for its primitive values or calling the writeObject method of ObjectOutput for objects, strings and arrays.

Throws: IOException
Includes any I/O exceptions that may occur
readExternal
 public abstract void readExternal(ObjectInput in) throws
	  IOException, ClassNotFoundException
	  
The object implements the readExternal method to restore its contents by calling the methods of DataInput for primitive types and readObject for objects, strings and arrays. The readExternal method must read the values in the same sequence and with the same types as were written by writeExternal.

Throws: IOException
Includes any I/O exceptions that may occur
Throws: ClassNotFoundException
If the class for an object being restored cannot be found.


© Ivan Luiz Marques Ricarte
DCA/FEEC/UNICAMP

Last modified: Tue Nov 30 12:43:22 EDT 1999