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