Recentemente, compilei o conhecimento básico do Java e as informações sobre serialização e deserialização de Java foram resolvidas em detalhes. Vou tomar uma nota aqui, esperando que também ajude amigos que leem este artigo.
1. O conceito de serialização e desserialização
O processo de conversão de um objeto em uma sequência de bytes é chamado de serialização de um objeto.
O processo de restauração de uma sequência de bytes em um objeto é chamado de deserialização de um objeto.
Existem dois usos principais para a serialização de objetos:
1) salvar a sequência de bytes de objetos permanentemente no disco rígido, geralmente em um arquivo;
2) Transfira a sequência de bytes de objetos na rede.
Em muitas aplicações, certos objetos precisam ser serializados, para que deixem o espaço da memória e passem para o disco rígido físico para armazenamento a longo prazo. Por exemplo, o mais comum é o objeto de sessão no servidor da web. Quando 100.000 usuários acessam simultaneamente, 100.000 objetos de sessão podem aparecer e a memória pode não ser capaz de suportá -la. Portanto, o contêiner da web serializa algumas verificações no disco rígido primeiro e aguarda até que seja usado e restaurará os objetos salvos no disco rígido na memória.
Quando dois processos estão se comunicando remotamente, eles podem enviar vários tipos de dados um para o outro. Não importa o tipo de dados, eles serão transmitidos na rede na forma de uma sequência binária. O remetente precisa converter esse objeto Java em uma sequência de bytes para ser transmitida na rede; O receptor precisa restaurar os bytes em um objeto Java.
2. API de serialização na biblioteca da classe JDK
java.io.ObjectOutputStream representa o fluxo de saída do objeto. Seu método writeObject (object obj) pode serializar o objeto OBJ especificado pelo parâmetro e gravar a sequência de bytes obtida em um fluxo de saída de destino.
java.io.ObjectInputStream representa o fluxo de entrada do objeto. Seu método readObject () lê seqüências de bytes de um fluxo de entrada de origem, os desapealiza em um objeto e as devolve.
Somente objetos de classes que implementam interfaces serializáveis e externizáveis podem ser serializadas. A interface externizável herda da interface serializável. As classes que implementam a interface externizável controlam completamente o comportamento de serialização, enquanto as classes que implementam apenas a interface serializável podem adotar o método de serialização padrão.
A serialização do objeto inclui as seguintes etapas:
1) Crie um fluxo de saída de objeto, que pode envolver outro tipo de fluxo de saída de destino, como o fluxo de saída de arquivo;
2) Escreva o objeto através do método writeObject () do fluxo de saída do objeto.
As etapas para a desaperação de um objeto são as seguintes:
1) Crie um fluxo de entrada de objeto que possa envolver um tipo diferente de fluxo de entrada de origem, como o fluxo de entrada de arquivo;
2) Leia o objeto através do método readObject () do fluxo de entrada do objeto.
Serialização de objetos e exemplos de desigualdade:
Defina uma classe de pessoa para implementar a interface serializável
1 importar java.io.Serializable; 2 3 /** 4 * <P> ClasseName: Pessoa <P> 5 * <P> Descrição: Teste Serialização e Deserialização do Objeto <p> 6 * @Author Xudp 7 * @Version 1.0 V 8 * @CreateTime 2014-6-9 12 12:33:25 9 * /10 Pessoa pública Implementa IdentrAlable {12 12 12 12 /12 /12 /12 /12 /12 /12 /12 12 / * * SerialversionUid = -5809782578272943999l; 16 private INT AGE; 17 Nome de cordas privadas; 18 sexo privado de cordas; 19 20 public int getage () {21 Idade de retorno; 22} 23 24 string public getName () {25 Nome de retorno; 26} 27 28 28 Public String () (29 Return sexo; idade; 34} 35 36 Public void setName (nome da string) {37 this.name = nome; 38} 39 40 public void setSex (sexo de string) {41 this.sex = sexo; 42} 43}Serialize e desserialize objetos de classe
importar java.io.file; importar java.io.fileInputStream; importar java.io.filenotfoundException; importar java.io.fileOutputStream; import java.io.ioexception; import java.io.objectinteam; importxtxturx /bjectStream; TestObJSerializeAndDeSerialize <p> * <p> Descrição: Serialização e deserivação de objetos de teste <P> * @Author Xudp * @version 1.0 V * @createTime 2014-6-9 03:17:25 Public Public. Serializeperson (); // serializar a pessoa do objeto Pessoa P = DeserializePerson (); // Deserial Perons Object System.out.println (messageFormat.Format ("Nome = {0}, Age = {1}, sexo = {2}", P.GetName (), P.Getage (), P.Sex () ()), } / ** * MethodName: Serializeperson * Descrição: serialize o objeto de pessoa * @author xudp * @throws fileNotfoundException * @THOWSows IoException * / private estático void serializePerson () lança fileNotFoundException, ioexception {Person = nova pessoa (); pessoa.setName ("gacl"); Person.setage (25); pessoa.SetSex ("masculino"); // ObjectOutputStream Fluxo de saída do objeto, armazene o objeto Pessoa no arquivo Person.txt no disco E e preencha a operação de serialização do objeto Pessoa. ObjectOutputStream oo = new ObjectOutputStream (new FileOutputStream (novo arquivo ("e: /person.txt"))); oo.WriteObject (pessoa); System.out.println ("A serialização do objeto de pessoa foi com sucesso!"); oo.close (); }/** * MethodName: DeSerializeperson * Descrição: objeto deseserializeperson * @Author xudp * @return * @throws Exceção * @THOWSox IoException */private static deseserializeperson () lança (newInputInputin); Pessoa pessoa = (pessoa) OIS.readObject (); System.out.println ("Person Object Deserialization com sucesso!"); pessoa de volta; }}Os resultados da execução do código são os seguintes:
Após a serialização da pessoa com sucesso, um arquivo de pessoa.txt foi gerado no disco e, enquanto a pessoa deseralizante é usada para ler a pessoa.txt de e disco.
3. O papel do SerialversionUid
Seri al versi ui d: literalmente significa número de versão serializada. Todas as classes que implementam a interface serializável têm uma variável estática representando o identificador de versão serializada.
private estático final serialversionuid
Se o SerialversionUid não for adicionado à classe, o aviso a seguir será exibido.
Clicar com o mouse exibirá uma caixa de diálogo que gera serialversionUid, como mostrado na figura abaixo:
Existem duas maneiras de gerar serialversionUid:
O serialversionUid gerado dessa maneira é 1L, por exemplo:
private estático final serialversionUid = 1L;
O serialversionuid gerado dessa maneira é gerado com base no nome da classe, nome da interface, método e atributo etc., por exemplo:
private estático final serialversionUid = 4603642343377807741L;
Após a adição, o aviso não aparecerá, como mostrado abaixo:
Depois de falar sobre isso, qual é o uso do SerialversionUid (número de versão serializada)? Vamos usar o exemplo a seguir para ilustrar o papel do SerialversionUid e ver o seguinte código:
1 importar java.io.File; 2 importar java.io.fileInputStream; 3 importar java.io.filenotfoundException; 4 importar java.io.FileOutputStream; 5 importar java.io.ioException; 6 importar java.io.ObjectInputStream; 7 importar java.io.ObjectOutputStream; 8 importar java.io.Serializable; 9 10 Classe pública testSerialVersionUid {11 12 public static void main (string [] args) lança exceção {13 SerializeCustomer (); // serializa o objeto do cliente 14 cliente = serrializeCustomer (); * @author xudp22 * @throws fileNotfoundException23 * @THOWSEXCECTIÇÃO24 */25 Void estático privado serializeCustomer () lança filenotfoundException, 26 ioException {27 Cliente do cliente = novo cliente ("gacle", 25); 28 // ObjectTriepTratut Freampest29 ObjectTUT29 Customer = Novo Cliente ("GacL", 25); 28 // ObjectStUsTrActTert. FileOutputStream (30 novo arquivo ("e: /customer.txt"))); 31 oo.writeObject (cliente); 32 system.out.println ("serialização do objeto do cliente com sucesso!"); 33 oo.close (); 34} 35 36 /** 37 * XUDP40 * @Return41 * @THOWSECTION42 * @THOWSECTIONCECCIONS43 */44 O cliente estático privado DeSerializeCustomer () lança exceção, ioException {45 ObjectInputStream Ois = new ObjectInputStream (newInputStream (46 Novo File ("E://Customer.tomer.tomer.ttomer.ttream (newInputStream (46 Novo File (" e:/: /customer.tomer.t) ")") OIS.readObject (); 48 System.out.println ("Deserialização do objeto do cliente foi bem -sucedido! "); 49 Retornar Cliente; 50} 51} 52 53 /** 54 * <P> ClasseName: Cliente <P> 55 * <P> Descrição: o cliente implementa a interface serializável e pode ser serializada <p> 56 * @author xudp57 * @version 1.0 V58 * @cretTime 2014-40 004400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 0. {61 // sem serialversionuid62 Nome da string privada; 63 private INT AGE; 64 65 CLIENTE PÚBLICO (Nome da String, Int Age) {66 this.name = Name; 67 this.age = Age; 68} 69 70 / * 71 * @methodname tostring72 * @Description Rewrite the Tostring () @MethOname tostring72 * @Description String75 * @see java.lang.Object#TOSTRING () 76 */77 @Substitua78 public string tostring () {79 returnResultados em execução:
Tanto a serialização quanto a desserialização foram bem -sucedidas.
Vamos modificar a classe do cliente e adicionar um atributo sexual adicional, como segue:
1 classe Customer implementa serializável {2 // Nenhum serialversionUID é definido no nome da string privada da classe 3 do cliente; 4 Idade Intrivid Int; 5 6 // novo atributo sexual 7 sexo privado de cordas; 8 9 CLIENTE PÚBLICO (NOME DE STRING, INT AGE) {10 this.name = Nome; 11 this.age = Age; 12} 13 14 Public Client (nome da string, Int Age, String Sex) {15 this.name = nome; 16 this.age = Age; 17 theSting22 * @sexo; xudp24 * @return string25 * @see java.lang.Object#tostring () 26 */27 @substituir28 public string tostring () {29 retornar "nome =" + nome + ", idade =" + idade; 30} 31}Em seguida, execute a operação de desamificação e as seguintes informações de exceção serão lançadas:
1 Exceção no thread "Main" java.io.InvalidClassexception: Cliente; 2 Classe local incompatível: 3 ClassDESC SerialversionUid = -881755999999432325, 4 classe local SerialversionUid = -5182532647273106745
Isso significa que a classe no fluxo de arquivos e a classe no caminho de classe, ou seja, a classe modificada, são incompatíveis. Eles estão sob as considerações do mecanismo de segurança. O programa lança um erro e se recusa a carregar. E daí se realmente precisarmos adicionar um campo ou método após a serialização? O que devo fazer? Isso é para especificar o serialversionUid. No exemplo testSerialVersionUid, se o serialversionuid da classe do cliente não for especificado, o compilador Java executará automaticamente um algoritmo de resumo para esta classe, semelhante ao algoritmo de impressão digital. Enquanto o arquivo tiver mais um espaço, o UID resultante será completamente diferente, o que pode ser garantido que esse número é único entre tantas classes. Portanto, depois de adicionar um campo, uma vez que o SerialversionUID não é especificado, o compilador gera um UID para nós, o que obviamente não é o mesmo que o salvo no arquivo antes, portanto, há dois erros com números de versão de serialização inconsistentes. Portanto, desde que especifiquemos serialversion UID, podemos adicionar um campo ou método após a serialização sem afetar a restauração posterior. O objeto restaurado ainda pode ser usado e também há mais métodos ou atributos a serem usados.
Em seguida, continue a modificar a classe do cliente e especificar um SerialversionUid para o cliente. O código modificado é o seguinte:
CLIET CLIENTE implementa serializável { / ** * serialversionUid (número da versão serializada) definido na classe do cliente * / private estático final serialversionuid = -5182532647273106745l; nome de string privado; private Int Age; // novo atributo sexual // sexo privado de cordas; cliente público (nome da string, Int Age) {this.name = name; this.age = idade; } /*public Customer (nome da string, Int Age, String Sex) {this.Name = Name; this.age = idade; this.sex = sexo; } *// * * @MethodName ToString * @Description Reescreva o método tostring () da classe de objeto * @author xudp * @return string * @see java.lang.Object#tostring () */ @Override string tostring () {retorno "Nome =" " }}Reexecute a operação de serialização, serialize o objeto do cliente para o armazenamento de arquivos do cliente.txt no disco rígido local, depois modifique a classe do cliente e adicione o atributo sexual. O código de classe do cliente modificado é o seguinte:
CLIET CLIENTE implementa serializável { / ** * serialversionUid (número da versão serializada) definido na classe do cliente * / private estático final serialversionuid = -5182532647273106745l; nome de string privado; private Int Age; // novo sexo atributo sexo privado de cordas; cliente público (nome da string, Int Age) {this.name = name; this.age = idade; } public Customer (nome da string, Int Age, String Sex) {this.Name = Name; this.age = idade; this.sex = sexo; } / * * @MethodName ToString * @Description Reescreva o método tostring () da classe de objeto * @author xudp * @return string * @see java.lang.Object#tostring () * / @Override public string tostring () {retorno "nome =" + " +",, Age = "; }}Execute a operação de desamificação, e a Desexence será bem -sucedida desta vez, como mostrado abaixo:
4. O valor do SerialversionUid
O valor do SerialversionUID é gerado automaticamente pelo ambiente de tempo de execução Java com base nos detalhes internos da classe. Se o código -fonte da classe for modificado e recompilado, o valor do serialversionUid do arquivo de classe recém -gerado também poderá mudar.
O valor padrão do serialversionUid de uma classe depende inteiramente da implementação do compilador Java. Para a mesma classe, a compilação com diferentes compiladores Java pode levar a diferentes serialversionuids e também pode ser a mesma. Para melhorar a independência e a certeza do SerialversionUid, é altamente recomendável definir o SerialversionUid exibido em uma classe serializável, atribuindo -lhe um valor claro.
Existem dois propósitos para definir explicitamente o SerialversionUid:
1. Em alguns casos, espera -se que diferentes versões da classe sejam compatíveis com a serialização, por isso é necessário garantir que diferentes versões da classe tenham o mesmo serialversionUid;
2. Em alguns casos, não se espera que diferentes versões da classe sejam compatíveis com a serialização; portanto, é necessário garantir que diferentes versões da classe tenham diferentes serialversionuids.
Obrigado pela leitura, espero que isso possa ajudá -lo. Obrigado pelo seu apoio a este site!