Esse processo também pode ser implementado através da rede, que pode primeiro criar um objeto na máquina Windows, serializar-o e enviá-lo para uma máquina Unix sobre a rede e depois remontá-la com precisão. Por que cada um dos objetos de RMI, Socket, JMS e EJB pode passar por Java?
O mecanismo de serialização do objeto Java geralmente tem dois usos:
Java Javabeans: as informações de status do feijão geralmente são configuradas no tempo de design. Leia o estado do objeto para reconstruir o objeto e restaurar o estado do programa.
O RMI permite que objetos em máquinas remotas sejam operadas como em máquinas nativas;
Podemos serializar as classes fazendo com que as classes implementem a interface java.io.Serializable. Esta interface é uma interface do fabricante. Ou seja, para a classe implementá -la, a interface não precisa implementar nenhum método. É usado principalmente para notificar as máquinas virtuais Java (JVMS) que um objeto precisa ser serializado.
Há alguns pontos que precisamos esclarecer para isso:
Nem todas as classes podem ser serializadas.
Existem muitas classes básicas em Java que implementaram interfaces serializáveis, como string, vetor, etc. Mas, por exemplo, a hashtable não implementa a interface serializável.
Existem duas classes principais para leitura ou gravação de objetos para fluxos: ObjectOutputStream e ObjectInputStream.ObjectOutputStream fornece um método WriteObject usado para gravar objetos no fluxo de saída, e o ObjectInputStream fornece um método ReadObject para ler objetos do fluxo de entrada. Objetos usando esses métodos devem ter sido serializados. Ou seja, a interface serializável deve ter sido implementada. Se você deseja escrever um objeto de hashtable, terá uma exceção.
O processo de serialização é escrever objetos e ler objetos do fluxo de bytes. Depois de converter o estado do objeto em um fluxo de bytes, você pode salvá -lo em um arquivo usando várias classes de fluxo de bytes no pacote java.io, tubar -se em outro thread ou enviar dados de objeto para outro host sobre uma conexão de rede. A função de serialização do objeto é muito simples e poderosa e é usada em RMI, Socket, JMS e EJB. O problema de serialização do objeto não é o tópico mais emocionante da programação de rede, mas é muito importante e tem muitos significado prático.
A serialização do objeto pode implementar objetos distribuídos. Principais aplicativos como: RMI usa a serialização do objeto para executar serviços em hosts remotos, assim como a execução de objetos nas máquinas locais.
A serialização do objeto Java não apenas mantém os dados de um objeto, mas também salva recursivamente os dados de cada objeto referenciado pelo objeto. Toda a hierarquia de objetos pode ser gravada em um fluxo de bytes, salva em um arquivo ou passada em uma conexão de rede. A serialização do objeto pode ser usada para executar "cópia profunda" do objeto, ou seja, copiando o próprio objeto e o próprio objeto referenciado. Serializando um objeto pode resultar em toda a sequência de objetos.
A serialização do Java é relativamente simples e geralmente não requer a gravação de código personalizado para salvar e restaurar o estado do objeto. Os objetos de classe que implementam a interface java.io.Serializable podem ser convertidos ou recuperados de fluxos de bytes sem adicionar nenhum código à classe. Somente em casos raros são o código personalizado necessário para salvar ou restaurar o estado do objeto. Observe aqui: nem todas as classes podem ser serializadas e algumas classes não podem ser serializadas.
Mecanismo de serialização:
A serialização é dividida em duas partes: serialização e desserialização. A serialização é a primeira parte desse processo, dividindo os dados em um fluxo de bytes para armazenamento em um arquivo ou transmissão em uma rede. A desserialização é abrir o fluxo de bytes e reconstruir o objeto. A serialização do objeto não apenas requer a conversão do tipo de dados básico em representação de bytes, mas às vezes também recuperando os dados. A recuperação de dados requer uma instância do objeto que restaura dados. O processo de serialização no ObjectOutputStream é conectado a um fluxo de bytes, incluindo o tipo de objeto e as informações da versão. Durante a desserialização, a JVM gera uma instância de objeto com informações do cabeçalho e, em seguida, copia os dados do fluxo de bytes do objeto para os membros dos dados do objeto. Vamos explicar em duas partes:
Processando Fluxo de Objetos: ( Processo de Serialização e Processo de Deserialização)
O pacote java.io possui duas classes que serializam objetos. ObjectOutputStream é responsável por escrever objetos em um fluxo de bytes, e o ObjectInputStream reconstrua objetos de um fluxo de bytes.
Vamos primeiro entender a classe ObjectOutputStream. A classe ObjectOutputStream estende a interface DataOutput.
O método writeObject () é o método mais importante para a serialização do objeto. Se o objeto contiver referências a outros objetos, o método writeObject () serializa recursivamente esses objetos. Cada objectOutputStream mantém uma tabela de referência de objeto serializada para impedir que várias cópias do mesmo objeto sejam enviadas. (Isso é importante) Como o WriteObject () pode serializar todo o conjunto de objetos referenciados cruzados, a mesma instância do ObjectOutputStream pode ser acidentalmente solicitada para serializar o mesmo objeto. Neste momento, a serialização anti -reference é realizada em vez de escrever no fluxo de bytes de objeto novamente.
Em seguida, vamos entender a classe ObjectOutputStream a partir do exemplo.
A cópia do código é a seguinte:
// serializa a data de hoje em um arquivo.
FileOutputStream f = new FileOutputStream ("tmp");
ObjectOutputStream S = new ObjectOutputStream (f);
S.WriteObject ("Today");
S.WriteObject (new Date ());
s.flush ();
Agora, vamos entender a classe ObjectInputStream. É semelhante ao ObjectOutputStream. Ele estende a interface do datainput. Os métodos no ObjectInputStream reflete o método público de ler tipos de dados básicos Java no DatainputStream. O método readObject () desaperializa um objeto de um fluxo de bytes. Cada vez que o método readObject () é chamado, o próximo objeto no fluxo é retornado. O fluxo de bytes de objeto não transmite o bytecode da classe, mas inclui o nome da classe e sua assinatura. Quando o ReadObject () recebe o objeto, o JVM carrega a classe especificada no cabeçalho. Se esta classe não puder ser encontrada, o ReadObject () lança um ClassNotFoundException. O restante dos métodos ObjectInputStream são usados para personalizar o processo de desserialização.
Exemplos são os seguintes:
A cópia do código é a seguinte:
// Deserialize Objetos da String e Objetos de Data do arquivo
FileInputStream in = new FileInputStream ("tmp");
ObjectInputStream s = new ObjecjotInputStream (in);
String Today = (string) s.readObject ();
Data data = (data) s.readObject ();
Processo de serialização personalizada:
A serialização geralmente pode ser feita automaticamente, mas às vezes o processo pode ser controlado. O Java pode declarar as classes como serializáveis, mas ainda podem controlar manualmente os membros de dados declarados como estáticos ou transitórios.
Exemplo: uma classe de serialização muito simples.
A cópia do código é a seguinte:
classe pública SimppleSerializableClass implementa serializável {
String stoday = "Today:";
data transitória dttoday = new Date ();
}
Ao serializar, todos os membros da classe devem ser serializáveis, exceto aqueles declarados como transitórios ou estáticos. Declarar a variável como transitória informa à JVM que seremos responsáveis por serializar os argumentos. Depois de declarar um membro de dados como transitório, o processo de serialização não pode adicioná -lo ao fluxo de bytes de objeto e não há dados enviados do membro de dados transitórios. Ao deseralizar os dados posteriormente, o membro de dados precisa ser reconstruído (porque faz parte da definição de classe), mas não contém nenhum dados porque esse membro de dados não escreve nenhum dados no fluxo. Lembre -se de que os fluxos de objetos não serializam estáticos ou transitórios. Nossa classe precisa usar os métodos WriteObject () e ReadObject () para processar esses membros de dados. Ao usar os métodos WriteObject () e ReadObject (), você também deve prestar atenção à leitura desses membros de dados na ordem em que estão escritos.
Alguns dos códigos sobre como usar a serialização personalizada são os seguintes
A cópia do código é a seguinte:
// Reescreva o método writeObject () para lidar com os membros transitórios.
public void writeObject (objectOutputStream OutputStream) lança ioexception {
outputStream.DefaultWriteObject (); // Faça o método WriteObject () personalizado para
// Use a lógica interna na serialização automática.
outputStream.WriteObject (Osocket.getineTAddress ());
outputStream.WriteInt (Osocket.getport ());
}
// Reescreva o método readObject () para receber membros transitórios.
private void readObject (objectInputStream inputStream) lança ioexception,
ClassNotfoundException {
inputStream.DefaultretoBject (); // DefaulTreadObject () Suplementos automáticos de serialização automática
Inetaddress oaddress = (inetaddress) inputStream.readObject ();
int iport = inputStream.readInt ();
OSocket = novo soquete (Oaddress, iport);
iid = getId ();
dttoday = new Date ();
}
Personalize completamente o processo de serialização:
Se uma classe é completamente responsável por sua própria serialização, ela implementa a interface externizável em vez da interface serializável. A definição de interface externizável inclui dois métodos WriteExternal () e ReadExternal (). Esses métodos podem ser usados para controlar como os membros do objeto são gravados em fluxos de bytes. , não há serialização automática. Preste atenção aqui. A classe de declaração implementa interfaces externizáveis com riscos significativos de segurança. Os métodos WriteExternal () e ReadExternal () são declarados públicos, e classes maliciosas podem usar esses métodos para ler e gravar dados de objeto. Se o objeto contiver informações confidenciais, tenha cuidado extra. Isso inclui o uso de soquetes seguros ou criptografar todo o fluxo de bytes. Nesse ponto, aprendemos o conhecimento básico da serialização.