Middle
Como tornar uma classe em Java imutável?
sobes.tech IA
Resposta da IA
Para tornar uma classe em Java imutável, deve seguir-se os seguintes princípios:
- Marcar a classe como
final. Isto impedirá a herança, que pode levar a alterações no estado. - Tornar todos os campos da classe privados (
private). Isto limitará o acesso direto aos campos de fora da classe. - Não fornecer setters (métodos para modificar o estado dos campos).
- Tornar todos os campos mutáveis da classe
final. Isto garante que as referências a objetos mutáveis não possam ser alteradas após a inicialização. - Se a classe contiver referências a objetos mutáveis (por exemplo,
java.util.Date, coleções), ao retorná-los dos getters ou passá-los ao construtor, deve criar e devolver cópias desses objetos. Isto é chamado de "cópia profunda".
Exemplo:
// Exemplo de classe imutável
final class ImmutablePerson {
private final String name;
private final int age;
private final List<String> hobbies; // Campo mutável
// Construtor com cópia profunda dos campos mutáveis
public ImmutablePerson(String name, int age, List<String> hobbies) {
this.name = name;
this.age = age;
// Criar uma cópia da lista hobbies
this.hobbies = new ArrayList<>(hobbies);
}
// Getters
public String getName() {
return name;
}
public int getAge() {
return age;
}
// Devolver uma cópia da lista hobbies para evitar alterações externas
public List<String> getHobbies() {
return Collections.unmodifiableList(new ArrayList<>(this.hobbies));
}
// Sobrescrever toString para conveniência
@Override
public String toString() {
return "ImmutablePerson{" +
"name='" + name + '\'' +
", age=" + age +
", hobbies=" + hobbies +
'}';
}
}
Exemplo de uso:
// Exemplo de uso de uma classe imutável
List<String> initialHobbies = new ArrayList<>();
initialHobbies.add("Reading");
initialHobbies.add("Hiking");
ImmutablePerson person = new ImmutablePerson("Alice", 30, initialHobbies);
// Tentar modificar a lista obtida resultará numa exceção
List<String> retrievedHobbies = person.getHobbies();
// retrievedHobbies.add("Coding"); // Lançará UnsupportedOperationException
// A alteração da lista original não afetará o objeto ImmutablePerson
initialHobbies.add("Painting");
System.out.println(person); // Saída: ImmutablePerson{name='Alice', age=30, hobbies=[Reading, Hiking]}
System.out.println(initialHobbies); // Saída: [Reading, Hiking, Painting]