DEV Community

Cover image for serialVersionUID: Onde vive? Como funciona? Para que serve? Afinal, qual é a desse cara?
Rossalli
Rossalli

Posted on

serialVersionUID: Onde vive? Como funciona? Para que serve? Afinal, qual é a desse cara?

Todo mundo que programa em Java já se deparou com ele, o famoso serialVersionUID. Mas a pergunta que fica é: você sabe qual a sua finalidade?

Bora entender juntos nesse artigo um pouco mais sobre a finalidade do tão conhecido mas muitas vezes incompreendido serialVersionUID.

Jovem gafanhoto..você já ouviu falar de serialização?

Antes de falar sobre o serialVersionUID é importante darmos um passo atrás e entender sobre outro conceito importante e tudo a ver com o assunto que estamos abordando aqui: serialização.

A serialização basicamente consiste em transformar um objeto Java em uma cadeia de bytes para que ele possa ser manipulado e transportado (seja via rede ou salvo em disco) de maneira mais fácil e sem perda de dados.

Fazendo uma analogia? Imagine que teletransporte seja possível e que eu tenha um corpo humano na pequena e pacata Miracema do Norte e desejo transportá-lo via teletransporte até Paris, na França. Pra isso eu transformo esse corpo humano em um conjunto específico de átomos (facilitando o transporte) e ao chegar no meu destino francês retorno ele ao seu estado humano reagrupando os átomos novamente. Trazendo para o mundo java: serialização e deserialização!

O grande x da questão (inclusive quando falamos de teletransporte rs) é: como garantir que os bytes mantenham uma estrutura padrão e seja possível retornar ao estado original (desserialização) sem problemas?

É aí que o serialVersionUID aparece.

O serialVersionUID identifica a versão da classe (.class) que foi usada durante o processo de serialização. O ideal é sempre utilizar as mesmas versões de .class, mas às vezes isso não será possível. Dessa forma, com o auxílio do serialVersionUID não é necessário que os arquivos .class sejam o mesmo para que o processo de serialização ocorra com sucesso, ele só precisa ser compatível.

E o que acontece se esse valor não for compatível? Ou seja, o valor do serialVersionUID utilizado durante a serialização é diferente do da deserialização? Uma exceção do tipo java.io.InvalidClassException é lançada!

Atenção: para um objeto estar apto para passar por esse processo de serialização/desserialização sua classe deve obrigatoriamente implementar a interface java.io.Serialize.

Image description

OK… mas como o serialVersionUID é gerado?

Existem duas formas de geração: implícita e explícita.

Gerando de forma implícita

A forma implícita é a realizada de forma automática pela JVM no momento de compilação. Ou seja, uma vez que não façamos isso explicitamente a JVM se encarrega disso. Para realizar essa geração implícita é considerado uma série de informações:

  • nome da classe e seus modificadores
  • atributos e seus modificadores
  • nome das interfaces que implementa
  • superclasses
  • etc (veja a doc para saber mais) Esses elementos são agrupados e um hash é aplicado levando isso em consideração, gerando assim o número serial.

Então cuidado: não é um valor aleatório!

Apesar da JVM cuidar disso, existem alguns problemas em realizar a geração dessa forma. Qualquer alteração nos elementos gerará um novo valor e aí ocorre a exceção java.io.InvalidClassException que comentamos ali em cima.

Mas pode acontecer que uma alteração realizada na classe não cause nenhum impacto e você queira que a compatibilidade continue ocorrendo normalmente. É aí que entra a geração de forma explícita!

Gerando de forma explícita

A forma explícita é a realizada via código. Com ela eu garanto e digo quando uma classe será ou não compatível de acordo com o valor explicitamente informado por para o serialVersionUID.

Existem três formas de fazer isso:

1. Informando um valor padrão, o famoso serialVersionUID = 1L:

Image description

2. Solicitando que a IDE gere um pra você:

Image description
Veja como gerar via:

3. Utilizando a ferramenta serialver do JDK:

Compile a classe desejada, por exemplo:

javac Dinosaur.java

Esse comando ira criar o Dinosaur.class. Em seguida utilize o serialver:

serialver Dinosaur

Ele irá retornar algo como:

Dinosaur: private static final long serialVersionUID = -3004201936381695859L;

Curiosidade: Esse problema de incompatibilidade do serialVersioUID já até aconteceu entre versões do Java sabia? Entre as versões 1.3 e 1.4. Para saber mais confere aqui :)

Conclusão:

Quem diria que um único atributo tivesse tanto conteúdo não é? Apesar de não ser um recurso explicitamente utilizado com frequência, é importante entender seu funcionamento a fim de evitar problemas futuros e é claro entender mais a fundo o código que se escreve.

E por ora é isso pessoal! Espero que tenham gostado do conteúdo.

Deixe sua dúvida, comentários ou feedbacks aqui ou nas minhas redes :)

Esse artigo também está disponível no Linkedin e no Medium.

Referências:

https://www.oracle.com/br/technical-resources/articles/java/serialversionuid.html

https://blog.algaworks.com/serialversionuid/

https://www.alura.com.br/artigos/entendendo-o-serialversionuid

https://mkyong.com/java/how-to-generate-serialversionuid/

https://www.devmedia.com.br/serializacao-de-objetos-em-java/23413

http://www.herongyang.com/Java-Tools/serialver-serialVersionUID-Generator.html

Top comments (0)