Sobes.tech
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:

  1. Mark the class as final. This prevents inheritance, which could lead to changing the state.
  2. Make all class fields private (private). This restricts direct access to the fields from outside the class.
  3. Do not provide setters (methods to modify the state of fields).
  4. Make all mutable class fields final. This ensures that references to mutable objects cannot be changed after initialization.
  5. 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]
How to make a class in Java immutable? — Java - sobes.tech