serialVersionUID: Onde vive? Como funciona? Para que serve? Afinal, qual é a desse cara?
Tags: java, programming
Published: 2022-05-04 17:33:46

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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qijh2e3k4t6ibu0ow1j3.png)

**OK… mas como o serialVersionUID é gerado?**

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

**<u>Gerando de forma implícita</u>**

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](https://www.oracle.com/br/technical-resources/articles/java/serialversionuid.html))
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!
**<u>
Gerando de forma explícita</u>**

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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/46ujpk1rbv0rbmyprr2p.png)

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

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ksdiwps88pt6dodq2c4n.png)
Veja como gerar via:
 

- [IntelliJ](https://mkyong.com/intellij/how-to-generate-serialversionuid-in-intellij-idea/)
- [Eclipse](https://stackoverflow.com/questions/14389733/automatically-generate-serial-version-uid-in-eclipse)

**3. Utilizando a ferramenta [serialver](https://docs.oracle.com/en/java/javase/17/docs/specs/man/serialver.html) 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](http://bugs.java.com/bugdatabase/view_bug.do?bug_id=4365406) :)

**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](https://linktr.ee/Rossalli) :)

Esse artigo também está disponível no [Linkedin](https://www.linkedin.com/pulse/serialversionuid-onde-vive-como-funciona-para-que-serve-rossalli/) e no [Medium](https://rossalli.medium.com/serialversionuid-onde-vive-como-funciona-para-que-serve-afinal-qual-%C3%A9-a-desse-cara-12c30b7409eb).

**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