Classes imutáveis são aquelas cujas instâncias não podem ser modificadas durante toda a vida útil do objeto, como por exemplo a classe String.
Ter um objeto imutável garante que seu valor não será modificado em nenhum lugar do sistema. Isso evita erros e problemas de concorrência que podem ocorrer quando vários threads tentam modificar o mesmo objeto ao mesmo tempo, por exemplo. Ou seja, uma classe imutável é naturalmente thread-safe. Além disso, esses objetos também podem ser armazenados em cache com segurança, pois não mudarão.
Para desenvolver uma classe imutável , até o java 16, é necessário:
- Criar a classe como "final", para garantir que ela não possa ser estendida, evitando que sub classes tenham acesso aos seus dados;
- Todos os campos devem ser declarados como finais e privados;
- Os atributos devem ser iniciados no construtor da classe;
- Não fornecer métodos que modifiquem o estado do objeto(setters);
public final class Pessoa{
private final String nome;
private final int idade;
public Pessoa(String nome, int idade){
this.nome = nome;
this.idade = idade;
}
public String getNome() {
return this.nome;
}
public int getIdade() {
return this.idade;
}
}
A partir do Java versão 16, é possível utilizar os records para essa finalidade.
Um Record é um tipo de classe que armazena dados, similar a um Java Bean e que já é imutável por padrão. Ela estende implicitamente de Record, e também são implicitamente final.
Essas classes ao serem criadas, já possuem os métodos equals, hashCode e toString() além de um método assessor para cada atributo, com o mesmo nome do atributo.
public record Pessoa(String nome, int idade) {}
Basta definir na declaração da classe os seus componentes(que neste exemplo são String nome e int idade) e você já "ganha" os metodos: nome(), idade(), equals, hashCode e toString().
Portanto, com apenas algumas linhas de código você pode criar uma classe de dados imutável. Isso pode ser muito útil quando precisamos representar objetos simples e garantir que seu estado não será alterado.
Observação: Records em Java, assim como as classes final, fornecem imutabilidade apenas para seus próprios componentes (atributos). Se uma classe record tiver referências a objetos mutáveis como componentes, esses objetos em si não se tornarão automaticamente imutáveis por estarem contidos em um record.
Exemplo: Um record "Pessoa" que tem um atributo que referencia a um objeto "Endereço" mutável. Neste caso, a instância de Pessoa em si é imutável, ou seja, você não pode alterar seus atributos depois que o objeto Pessoa é criado. No entanto, o "Endereço" ainda é mutável, o que significa que você pode modificar o endereço após a criação do objeto Pessoa. Exemplo:
Endereco endereco = new Endereco("Brasil", "Sao Paulo");
Pessoa pessoa = new Pessoa("Maria", endereco);
pessoa.getEndereco().setEstado("XXX");
Isso não é impedido pelo record, nem pelas classes final. Portanto, para garantir a imutabilidade certifique-se de que objetos imutáveis não estejam vinculados à objetos mutáveis ou ofereça cópias defensivas de quaisquer vínculos à objetos mutáveis.
Top comments (0)