Immutable class built on mutable underlying object

I’m currently reading the “Java Concurrency in Practice” by Brian Goetz. There are a plenty of brilliant code snippets here concerning concurrency in Java. So I want to analyze some of the examples to understand it more detailed.

Today we will talk about immutable objects which contain a mutable objects as fields, but still remains immutable. So let’s start from the code sample:

import java.util.HashSet;
import java.util.Set;

public final class ImmutableOnMutable {

    private final Set<String> names = new HashSet<>();

    public ImmutableOnMutable() {
        names.add("Alex");
        names.add("John");
        names.add("Paul");
    }

    public boolean isStored(String name) {
        return names.contains(name);
    }
}

This class is immutable because we effectively don’t have any possibilities to change it state from the outside.

  • It is final– that means this class can’t be extended;
  • The only field called names is final so this link can’t be updated with a new value. It also private and therefore unavailable from other classes (except for inner ones);
  • It has only one public constructor which is also fills names with values;
  • The only way to interact with this class from the outside is to use isStored method, which doesn’t affect the inner state of the class instance at all.

So despite the fact that we use a mutable HashSet the whole class remains immutable. There are no options for third-party classes to change the state of ImmutableOnMutable in any way.