Immutable class in java

Srikanth Dannarapu
Javarevisited
Published in
3 min readMar 17, 2023

We can create immutable classes by following these guidelines:

  1. Declare the class as final, so it cannot be subclassed.
  2. Make all fields private and final, so they cannot be modified after initialization.
  3. Do not provide any setters for the fields.
  4. Initialize all fields via constructor only, and make sure to deep-copy any mutable objects.
  5. If the class has any mutable objects as fields, return a copy of those objects instead of the original in getter methods.
  6. Make sure the class is thread-safe.

An example of an immutable class:

public final class Person {
private final String name;
private final int age;
private final List<String> hobbies;

public Person(String name, int age, List<String> hobbies) {
this.name = name;
this.age = age;
this.hobbies = new ArrayList<>(hobbies);
}

public String getName() {
return name;
}

public int getAge() {
return age;
}

public List<String> getHobbies() {
return new ArrayList<>(hobbies);
}
}

In this example, the Person class has three fields: name, age, and hobbies. All fields are private and final, and there are no setters provided for any of them. The hobbies field is an ArrayList, which is mutable, so we create a new ArrayList object in the constructor and copy the contents of the original list into it.

The getName and getAge methods simply return the value of their respective fields. The getHobbies method returns a copy of the hobbies field to prevent modification of the original list.

By following these guidelines, we can ensure that instances of the Person class are immutable and thread-safe.

Handling Mutable field in an Immutable class:

If the Person class has a mutable field such as Address, we need to take additional steps to ensure the immutability of the class. Here are some guidelines to follow:

  1. Declare the Address field as final and create a copy of it in the constructor to ensure that the instance variable is also immutable.
  2. If Address has its own mutable fields, such as List or Map, create a copy of those fields as well in the constructor.
  3. Return a copy of the Address object in the getter method to prevent modification of the original object.

An example of how to modify the Person class to handle a mutable field Address:

public final class Person {
private final String name;
private final int age;
private final Address address;

public Person(String name, int age, Address address) {
this.name = name;
this.age = age;
this.address = new Address(address.getStreet(), address.getCity(), address.getState(), new ArrayList<>(address.getHobbies()));
}

public String getName() {
return name;
}

public int getAge() {
return age;
}

public Address getAddress() {
return new Address(address.getStreet(), address.getCity(), address.getState(), new ArrayList<>(address.getHobbies()));
}
}

In this example, the Person class has an Address field, which has its own mutable field hobbies. To ensure immutability of the Person class, we create a new Address object in the constructor by copying the fields of the original Address object, including a new ArrayList object to copy the hobbies field. Similarly, in the getAddress() method, we return a copy of the Address object to prevent modification of the original object.

By following these guidelines, we can ensure that instances of the Person class are fully immutable and thread-safe, even if they contain mutable fields.

Advantages of immutable class:

There are several advantages of immutable classes in Java, including:

  1. Thread-safety: Immutable objects are inherently thread-safe since they cannot be modified after creation, making them ideal for use in multi-threaded environments.
  2. Security: Immutable objects cannot be modified by malicious code, preventing unexpected or unauthorized changes to data.
  3. Simplified code: Immutable classes can simplify code by eliminating the need for defensive copying of objects.
  4. Better performance: Immutable objects can be cached, shared, and reused, leading to better performance by reducing the need for object creation.
  5. Ease of testing: Immutable classes are easier to test since their state is fixed and cannot change during runtime, making it easier to write predictable and reliable tests.
  6. Consistency: Immutable classes enforce consistency, which can be useful in cases where you want to ensure that an object is created with a specific set of values that cannot be changed.

In summary, immutable classes provide a number of benefits that can make our code more secure, reliable, and efficient. By ensuring that objects cannot be modified after creation, immutable classes can improve thread-safety, simplify code, improve performance, and make it easier to test and maintain our code.

Thanks, before you go:

  • 👏 Please clap for the story and follow the author 👉
  • Please share your questions or insights in the comments section below. Let’s help each other and become better Java developers.
  • Let’s connect on LinkedIn

--

--