Middle
How to make a class in Java immutable?
sobes.tech AI
Answer from AI
To make a class in Java immutable, follow these principles:
- Mark the class as
final. This prevents inheritance, which could lead to changing the state. - Make all class fields private (
private). This restricts direct access to the fields from outside the class. - Do not provide setters (methods to modify the state of fields).
- Make all mutable class fields
final. This ensures that references to mutable objects cannot be changed after initialization. - If the class contains references to mutable objects (e.g.,
java.util.Date, collections), create and return copies of these objects when returning from getters or passing into the constructor. This is called "deep copying".
Example:
// Example of an immutable class
final class ImmutablePerson {
private final String name;
private final int age;
private final List<String> hobbies; // Mutable field
// Constructor with deep copying of mutable fields
public ImmutablePerson(String name, int age, List<String> hobbies) {
this.name = name;
this.age = age;
// Create a copy of the hobbies list
this.hobbies = new ArrayList<>(hobbies);
}
// Getters
public String getName() {
return name;
}
public int getAge() {
return age;
}
// Return a copy of the hobbies list to prevent external modifications
public List<String> getHobbies() {
return Collections.unmodifiableList(new ArrayList<>(this.hobbies));
}
// Override toString for convenience
@Override
public String toString() {
return "ImmutablePerson{" +
"name='" + name + '\'' +
", age=" + age +
", hobbies=" + hobbies +
'}';
}
}
Usage example:
// Usage example of an immutable class
List<String> initialHobbies = new ArrayList<>();
initialHobbies.add("Reading");
initialHobbies.add("Hiking");
ImmutablePerson person = new ImmutablePerson("Alice", 30, initialHobbies);
// Attempting to modify the retrieved list will throw an exception
List<String> retrievedHobbies = person.getHobbies();
// retrievedHobbies.add("Coding"); // Will throw UnsupportedOperationException
// Modifying the original list will not affect the ImmutablePerson object
initialHobbies.add("Painting");
System.out.println(person); // Output: ImmutablePerson{name='Alice', age=30, hobbies=[Reading, Hiking]}
System.out.println(initialHobbies); // Output: [Reading, Hiking, Painting]