Java - Serialização
Java fornece um mecanismo, chamado serialização de objetos, onde um objeto pode ser representado como uma sequência de bytes que inclui os dados do objeto, bem como informações sobre o tipo do objeto e os tipos de dados armazenados no objeto.
Depois que um objeto serializado é gravado em um arquivo, ele pode ser lido do arquivo e desserializado, ou seja, as informações de tipo e os bytes que representam o objeto e seus dados podem ser usados para recriar o objeto na memória.
O mais impressionante é que todo o processo é independente da JVM, o que significa que um objeto pode ser serializado em uma plataforma e desserializado em uma plataforma totalmente diferente.
Classes ObjectInputStream e ObjectOutputStream são fluxos de alto nível que contêm os métodos para serializar e desserializar um objeto.
A classe ObjectOutputStream contém muitos métodos de gravação para escrever vários tipos de dados, mas um método em particular se destaca -
public final void writeObject(Object x) throws IOException
O método acima serializa um Object e o envia para o fluxo de saída. Da mesma forma, a classe ObjectInputStream contém o seguinte método para desserializar um objeto -
public final Object readObject() throws IOException, ClassNotFoundException
Esse método recupera o próximo objeto do fluxo e desserializa-o. O valor de retorno é Object, portanto, você precisará convertê-lo em seu tipo de dados apropriado.
Para demonstrar como a serialização funciona em Java, vou usar a classe Employee que discutimos no início do livro. Suponha que tenhamos a seguinte classe Employee, que implementa a interface Serializable −
Exemplo
public class Employee implements java.io.Serializable {
public String name;
public String address;
public transient int SSN;
public int number;
public void mailCheck() {
System.out.println("Mailing a check to " + name + " " + address);
}
}
Observe que para uma classe ser serializada com sucesso, duas condições devem ser atendidas -
-
A classe deve implementar a interface java.io.Serializable.
-
Todos os campos da classe devem ser serializáveis. Se um campo não for serializável, ele deve ser marcado como transitório .
Se você está curioso para saber se uma Java Standard Class é serializável ou não, verifique a documentação da classe. O teste é simples:se a classe implementa java.io.Serializable, então ela é serializável; caso contrário, não é.
Serializando um objeto
A classe ObjectOutputStream é usada para serializar um Object. O programa SerializeDemo a seguir instancia um objeto Employee e o serializa em um arquivo.
Quando o programa termina de ser executado, um arquivo chamado employee.ser é criado. O programa não gera nenhuma saída, mas estuda o código e tenta determinar o que o programa está fazendo.
Observação − Ao serializar um objeto para um arquivo, a convenção padrão em Java é dar ao arquivo um .ser extensão.
Exemplo
import java.io.*;
public class SerializeDemo {
public static void main(String [] args) {
Employee e = new Employee();
e.name = "Reyan Ali";
e.address = "Phokka Kuan, Ambehta Peer";
e.SSN = 11122333;
e.number = 101;
try {
FileOutputStream fileOut =
new FileOutputStream("/tmp/employee.ser");
ObjectOutputStream out = new ObjectOutputStream(fileOut);
out.writeObject(e);
out.close();
fileOut.close();
System.out.printf("Serialized data is saved in /tmp/employee.ser");
} catch (IOException i) {
i.printStackTrace();
}
}
}
Desserializando um objeto
O programa DeserializeDemo a seguir desserializa o objeto Employee criado no programa SerializeDemo. Estude o programa e tente determinar sua saída -
Exemplo
import java.io.*;
public class DeserializeDemo {
public static void main(String [] args) {
Employee e = null;
try {
FileInputStream fileIn = new FileInputStream("/tmp/employee.ser");
ObjectInputStream in = new ObjectInputStream(fileIn);
e = (Employee) in.readObject();
in.close();
fileIn.close();
} catch (IOException i) {
i.printStackTrace();
return;
} catch (ClassNotFoundException c) {
System.out.println("Employee class not found");
c.printStackTrace();
return;
}
System.out.println("Deserialized Employee...");
System.out.println("Name: " + e.name);
System.out.println("Address: " + e.address);
System.out.println("SSN: " + e.SSN);
System.out.println("Number: " + e.number);
}
}
Isso produzirá o seguinte resultado -
Saída
Deserialized Employee... Name: Reyan Ali Address:Phokka Kuan, Ambehta Peer SSN: 0 Number:101
Aqui estão os seguintes pontos importantes a serem observados -
-
O bloco try/catch tenta capturar uma ClassNotFoundException, que é declarada pelo método readObject(). Para que uma JVM possa desserializar um objeto, ela deve ser capaz de localizar o bytecode da classe. Se a JVM não encontrar uma classe durante a desserialização de um objeto, ela lançará uma ClassNotFoundException.
-
Observe que o valor de retorno de readObject() é convertido em uma referência Employee.
-
O valor do campo SSN era 11122333 quando o objeto foi serializado, mas como o campo é transitório, esse valor não foi enviado ao fluxo de saída. O campo SSN do objeto Employee desserializado é 0.
Java