Good way to create a immutable class with modifiers (thread-safe) Good way to create a immutable class with modifiers (thread-safe) multithreading multithreading

Good way to create a immutable class with modifiers (thread-safe)


I recommend you take a look at Guava's immutable collections, such as immutable list and how they create lists from builders etc.

The idiom is the following:

List<String> list1 = ImmutableList.of("a","b","c"); // factory methodList<String> list2 = ImmutableList.builder() // builder pattern  .add("a")  .add("b")  .add("c")  .build();List<String> list3 = ...  // created by other meansList<String> immutableList3 = ImmutableList.copyOf(list3); // immutable copy, lazy if already immutable

I really like the idiom above. For an entity builder I would take the following approach:

Person johnWayne = Person.builder()  .firstName("John")  .lastName("Wayne")  .dob("05-26-1907")  .build();Person johnWayneClone = johnWayne.copy() // returns a builder!  .dob("06-25-2014")  .build();

The builder here can be obtained from an existing instance via the copy() method or via a static method on the Person class (a private constructor is recommended) that return a person builder.

Note that the above mimics a little Scala's case classes in that you can create a copy from an existing instance.

Finally, don't forget to follow the guidelines for immutable classes:

  • make the class final or make all getters final (if the class can be extended);
  • make all fields final and private;
  • initialize all fields in the constructor (which can be private if you provide a builder and/or factory methods);
  • make defensive copies from getters if returning mutable objects (mutable collections, dates, third party classes, etc.).


One possibility is to separate your interfaces surrounding such objects into an immutable variant (providing getters) and a mutable variant (providing getters and setters).

public interface Person {   String getName();}public interface MutablePerson extends Person {   void setName(String name);}

It doesn't solve the mutability of the object per se but it does offer some guarantees that when you pass around the object using the immutable interface reference, you know that the code you're passing this to won't change your object. Obviously you need to control the references to the underlying object and determine the subset of functionality that has control of a reference via the mutable interface.

It doesn't solve the underlying problem and I would favour immutable objects until I definitely need a mutable version. The builder approach works nicely, and you can integrate it within the object to give a modifier thus:

Person newPerson = existingPerson.withAge(30);


Why not make your fields final and your modifier methods directly create new objects?

public class Person {    private final String name, surname;    public Person(String name, String surname) {....}    // getters...    // and instead of setters    public Person withName(String newName) {       return new Person(newName, surname);             }}