Serialização em Java: tudo o que você precisa saber [2022]

Publicados: 2021-01-04

Com o boom cada vez maior do setor de TI, nossa confiança nele parece estar crescendo a cada dia que passa. Esse crescimento constante levou muitos profissionais a adotar linguagens de programação em uma tentativa de permanecerem relevantes no setor. Embora a indústria faça uso de vários idiomas para atender seus clientes, alguns idiomas são usados ​​com mais frequência do que outros. Java é uma dessas linguagens.

Independentemente de você ser um novato ou um veterano, um bom conhecimento de Java irá beneficiá-lo a cada passo de sua jornada de software. Como qualquer outra linguagem de programação, o Java também possui um programa abrangente próprio. É preciso praticar a língua diariamente para se apoderar de todos os vários conceitos que pontuam a língua. Um conceito que ajuda muito os usuários é a prática de serialização em Java.

Índice

Introdução

A serialização no contexto de Java refere-se ao processo no qual um objeto de código Java é sistematicamente convertido em um Byte Stream. Isso é feito para permitir a transferência eficiente do referido código de objeto de uma máquina virtual Java para outra. Posteriormente, isso permite sua recriação com a ajuda da desserialização. Usamos a serialização para atender a vários objetivos. Vamos dar uma olhada nos mais populares e relevantes na seção abaixo.

Por que a serialização é usada?

O fenômeno de representar um objeto como uma sequência de bytes tem seu quinhão de uso dentro do paradigma de programação. Quando o processo se estende para representar também os dados do objeto, a utilidade aumenta muito. Abaixo estão listados alguns dos usos mais comuns de serialização em Java.

Comunicação

A serialização em Java permite uma comunicação eficaz e rápida entre vários sistemas de computador. Essas unidades fazem uso de serialização e transmissão de objetos para facilitar o compartilhamento simultâneo e o design de vários objetos. Conseqüentemente, isso resulta em uma boa execução eventual também. No caso de bancos de dados volumosos, a serialização permite uma abordagem altamente simplificada para manipulação de objetos.

Cache

O cache, em um sentido mais amplo, refere-se ao método de armazenar informações para acessá-las posteriormente, investindo um tempo mínimo nelas. A serialização em Java solicita o armazenamento em cache minimizando o tempo consumido na desserialização de um objeto grande. É de conhecimento geral que o tempo gasto na construção de um objeto é muito maior quando comparado ao tempo que leva para a desserialização. Portanto, a serialização ajuda a otimizar esse consumo de tempo armazenando em cache os objetos relativamente maiores no mix.

Cópia profunda

Cópia profunda em Java refere-se ao processo de copiar objetos de uma árvore de forma que não dependa de nenhuma de suas versões anteriores que possam estar sujeitas a algum grau de alteração. Esse processo de clonagem é muito mais fácil adotando a serialização. Ao serializar o objeto em uma matriz de bytes e, em seguida, desserializá-lo, o usuário pode obter uma réplica do referido objeto.

Sincronização cruzada de máquinas virtuais Java

A principal vantagem de praticar a serialização está no fato de permitir que o usuário opere em diferentes JVMs. Uma vez adotada a serialização, não importa se essas JVMs estão trabalhando nas mesmas arquiteturas e sistemas operacionais ou não.

Persistência

Ao aplicar a serialização a um objeto, pode-se armazenar diretamente o estado do item sem qualquer inconveniente. Além disso, também permite que o usuário salve o estado mencionado em um banco de dados que pode ser recuperado posteriormente a qualquer momento no futuro.

Leia: Perguntas e respostas da entrevista de serialização Java

Serializando um Objeto - O Processo Envolvido

Antes de prosseguir com a serialização de um objeto, primeiro precisamos estabelecer se ele é serializável ou não. Agora, como determinamos isso? Um objeto em Java é serializável se e somente se sua classe ou qualquer uma de suas classes pai permitir a implementação da interface java.io.Serializable. Os critérios também são atendidos se essas classes também implementarem sua subinterface, que é java.io.Externalizable.

Conforme discutido acima, a sincronização cruzada de JVM é uma das aplicações mais potentes do uso de serialização. Quando serializamos um objeto, convertemos o estado desse objeto em um fluxo de bytes. Como resultado, torna-se possível transferir o objeto de uma Java Virtual Machine para outra. Consequentemente, esse fluxo de bytes também pode ser convertido novamente no objeto original.

Essa conversão também é chamada de desserialização. É o processo inverso de serialização em que o fluxo de bytes de um objeto do remetente que foi serializado anteriormente é recriado na extremidade receptora.

Vantagens da serialização em Java

Ao discutir os usos e aplicações da serialização nas seções anteriores, já lançamos alguma luz sobre seus vários méritos. Agora é hora de mergulhar mais fundo neles.

  • Uma das vantagens mais significativas da serialização é o fato de ser um recurso interno. Para implementar ou executar a serialização, você não precisa da ajuda de nenhum software de terceiros.
  • Mesmo para usuários iniciantes que estão apenas aprendendo, a serialização é um processo bastante fácil de aprender e entender.
  • Muitas vezes, os desenvolvedores vindos de diferentes origens de programação obtêm uma experiência de toque quando precisam lidar com as nuances de uma nova linguagem. No entanto, no caso da serialização, o processo é universal e, portanto, bastante familiar para todos os desenvolvedores.
  • Não só é fácil de usar e implementar, mas também é igualmente fácil de personalizar.
  • Atualmente, há uma série de tecnologias críticas que fazem uso da serialização em suas operações. Isso ocorre porque os fluxos de dados serializados suportam criptografia, autenticação, compactação e computação java segura.

Desvantagens da serialização em Java

Nenhuma linguagem de programação é cem por cento perfeita, e também não podem afirmar que são. Como resultado, os conceitos e os processos que os constituem também não são isentos de falhas. Aqui estão algumas das desvantagens gerais associadas ao processo de serialização.

  • Alguns processos de serialização exigem que a desserialização seja aplicada em conjunto também. Agora, a desvantagem de aplicar a desserialização é que ela torna os objetos frágeis. Como resultado, nunca há uma certeza completa de que o referido objeto será desserializado efetivamente.
  • Quando o processo de serialização é invocado, ele causa a criação de várias variáveis ​​transitórias. Essas variáveis ​​transitórias, quando criadas, ocupam espaço de memória extra. No entanto, muitas dessas variáveis ​​transitórias não são inicializadas porque o construtor não é chamado durante esses processos. Posteriormente, acabam afetando uma variação do Standard Java Flow.
  • Apesar de todas as suas otimizações de consumo de tempo, o processo de serialização é cada vez mais ineficiente quando se trata de utilização de memória.
  • O processo de serialização não oferece nenhum mecanismo de controle de transição para cada Standard Edition do Java. Como resultado, não é preferível ser usado em associação com aplicativos que precisam de acesso paralelo sem a exigência de APIs de terceiros.
  • Ao usar a serialização, muitas vezes é preciso comprometer a obtenção de um controle refinado para acessar os objetos.

Serialização vista através de uma lente prática

Até agora, discutimos o processo de serialização como um conceito teórico, incluindo suas várias vantagens e desvantagens. Agora é hora de mergulhar em uma discussão que nos permite visualizar a serialização do ponto de vista prático e sua implementação. Abaixo estão listados alguns casos que nos ajudam a entender a realização prática da serialização.

Deve ler: Propriedades e benefícios do JavaBeans: como você deve utilizar?

Serialização e Herança

A herança em Java é amplamente definida como o fenômeno no qual uma classe adquire ou herda os métodos e os campos de outra classe. A classe que herda as propriedades é chamada de subclasse, e a classe cujas propriedades são herdadas é chamada de superclasse. O termo superclasse também é usado de forma intercambiável com a classe base e a classe pai.

Nosso primeiro caso trata da serialização no contexto de superclasses. Geralmente, se uma superclasse é serializável, então suas subclasses também podem ser consideradas serializáveis ​​por padrão. Claro, isso é verdade apenas se a superclasse estiver implementando a interface Serializable. No entanto, também existem certos casos em que a subclasse pode ser serializada mesmo que a superclasse não implemente a interface Serializable.

Isso ocorre quando a subclasse consegue implementar a interface Serializable em sua única capacidade. Se a superclasse falhar em implementar a interface Serializable em qualquer circunstância, os objetos da subclasse poderão ser serializados manualmente quando a própria subclasse implementar a interface serializável.

Às vezes, o usuário também pode se deparar com uma terceira possibilidade. Essa possibilidade surge quando a superclasse é serializável, mas o usuário não precisa adotar o processo em relação à subclasse.

Em situações como essas, existem maneiras pelas quais a serialização indesejada da subclasse pode ser conscientemente evitada. Isso pode ser feito implementando os métodos writeObject() e readObject() na subclasse. No entanto, a implementação desses métodos por si só não é suficiente. Além de escrever esses métodos, o usuário também deve garantir que os referidos métodos não gerem NotSerializableException de sua implementação.

Serialização com a ajuda de um membro estático

Quando o processo de serialização é implementado, ele acaba ignorando os membros do campo estáticos no processo. Isso ocorre principalmente porque a serialização como um procedimento se preocupa em grande parte com o estado mais recente do objeto em questão. Como resultado, enquanto os dados associados a uma instância específica de uma classe são serializados com êxito, o campo de membro estático em conexão com ele não é.

Serialização em relação a documentos XML

A serialização de objetos Java para XML pode ser obtida de várias maneiras. Principalmente eles são realizados com a ajuda de XMLEncoder e XMLDecoder. O objetivo principal de serializar objetos Java para documentos XML é tentar limitar as várias desvantagens inerentes ao processo de serialização.

Um dos problemas mais relevantes no processo de serialização é que a lógica que salva e restaura os objetos serializados é baseada apenas na estrutura interna das classes constituintes. Ele não leva em consideração nenhuma das alterações que podem ter sido causadas a essas classes no tempo que decorre entre salvar o objeto e recuperá-lo. Posteriormente, isso resulta na falha iminente do processo de desserialização.

A serialização também dá origem a problemas de versão. Isso acontece quando o usuário salva um objeto usando uma versão da classe, mas tenta desserializar a mesma classe usando uma versão diferente ou nova da classe. Nesse caso, o processo de desserialização também falha.

Assim, para evitar todos esses problemas, alguns usuários preferem serializar objetos em Documentos XML em vez de adotar a abordagem convencional de serializá-los em formato binário. Além disso, a serialização de objetos Java para documentos XML também garante que o objeto se torne legível por humanos, facilitando assim um grau superior de conveniência.

Checkout: Perguntas e Respostas da Entrevista Java

Entendendo a interface externalizável

A interface Externalizável em Java é bastante semelhante à interface de serialização. A diferença está em suas habilidades para oferecer serialização personalizada. A interface externalizável oferece a opção de escolher os objetos que você deseja que sejam armazenados no fluxo, enquanto a interface de serialização não concede o mesmo privilégio.

Pode-se aproveitar a interface externalizável em java.io. A interface externalizável também fornece ao usuário dois métodos. O primeiro é o public void writeExternal(ObjectOutput out) lança IOException. O outro é o público void readExternal(ObjectOutput in) lança IOException.

Diferença entre serialização e externalização

Além de seus recursos para oferecer serialização personalizada, algumas outras variáveis-chave também diferenciam a serialização e a externalização. O segmento a seguir analisa-os mais de perto.

Implementação

Uma das principais diferenças entre as interfaces serializáveis ​​e as externalizáveis ​​reside na sua implementação. A interface externalizável espera que o usuário mencione explicitamente os objetos que deseja serializar. Este não é o caso quando se trata da interface serializável. Na interface serializável, todos os objetos e variáveis ​​são serializados, sem qualquer diferenciação, durante o tempo de execução.

Métodos

A interface Externalizável consiste principalmente em dois métodos. Estes são o método writeExternal() e o método readExternal(). A interface serializável, por outro lado, não inclui nenhum método.

Processar

Quando se está realizando o processo de serialização na interface externalizável, é concedido o privilégio de serialização customizada. Considerando que na interface serializável se submeteu ao processo de serialização padrão.

Compatibilidade e controle com versões anteriores

A Interface Externalizável suporta serialização sem ressalvas ao controle de versão em questão. O único problema com essa abordagem é que o próprio usuário tem que ser responsável ao serializar a superclasse. Pelo contrário, a interface de serialização requer que a mesma versão das JVMs esteja presente em ambas as extremidades. No entanto, ele permite uma serialização padrão de todos os objetos e classes, incluindo a superclasse também.

Construtor público No-Arg

Ao reconstruir o objeto serializado, a interface de externalização requer o uso do construtor público no-arg. Isso é diferente no caso da interface de serialização que não requer explicitamente o construtor no-arg, mas faz uso de reflexão para reconstruir os objetos e classes serializados.

Serialização em Java: as controvérsias

Existem algumas controvérsias que se ligam ao conceito de serialização em Java. Muitos deles se preocupam com a remoção da serialização como um procedimento em primeiro lugar. É amplamente considerado que os arquitetos da Oracle consideram há muito tempo remover a serialização do Java, pois consideram um erro horrível de 1997.

De acordo com sua pesquisa, as falhas no design do procedimento de serialização são tais que representam uma ameaça aos próprios dados. Nessa medida, Mark Reinhold em 1997 atribuiu quase um terço de todas as vulnerabilidades Java ao processo de serialização, mesmo afirmando que o quociente pode ser confortavelmente maior que isso também.

Portanto, há uma boa possibilidade de que a serialização como uma construção seja totalmente removida ou substituída dos anais do Java em suas próximas atualizações. Isso também pode ocorrer porque a maioria dos especialistas não considera a serialização uma opção idealista que iniciantes em Java podem implementar em seus projetos.

Leia também: Ideias e tópicos do projeto Java

Obtenha o curso de desenvolvimento de software das melhores universidades do mundo. Ganhe Programas PG Executivos, Programas de Certificado Avançado ou Programas de Mestrado para acelerar sua carreira.

Conclusão

Uma discussão e deliberação sobre serialização não pode ser concluída lançando alguma luz sobre algumas de suas melhores práticas. Aqui estão alguns que o usuário deve adotar para garantir a melhor experiência para si.

  • Para denotar campos serializáveis, deve-se usar a tag javadoc@serial.
  • Para arquivos que representam objetos serializados, é preferível usar a extensão .ser.
  • Normalmente, o processo de submeter campos estáticos ou transitórios à serialização padrão é desaprovado.
  • A menos que seja absolutamente obrigatório, deve-se, em todas as circunstâncias, tentar evitar a serialização de Classes Extensíveis.
  • Ao implementar a serialização, deve-se evitar que as classes internas se envolvam no processo de serialização.

Se você estiver interessado em aprender mais sobre Java, OOPs e desenvolvimento de software full-stack, confira o Programa PG Executivo do upGrad & IIIT-B em Desenvolvimento de Software Full-stack, projetado para profissionais que trabalham e oferece mais de 500 horas de treinamento rigoroso, Mais de 9 projetos e atribuições, status de ex-alunos do IIIT-B, projetos práticos práticos e assistência de trabalho com as principais empresas

Prepare-se para uma carreira do futuro

Inscreva-se agora para Mestrado em Engenharia de Software