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.
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:
2. Solicitando que a IDE gere um pra você:
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)