Harald Kirsch

genug Unfug.

2014-09-14

Java unmodifiable vs. immutable vs. recursively immutable

During my current experiments with abstract polynomials for Java, I thought that it would be good to implement them immutable and so searched the Internet for an immutable list for Java. What I found were blogs that use immutable and unmodifiable synonymously, as well as at least one blog which clearly makes the differences, as also explained in this stackoverflow answer.

For the sake of clarity, let me try to define three related concepts:

unmodifiable
shall denote an object that has no has methods itself that change its state,
immutable
shall denote an object that is unmodifiable and, in addition, makes defensive shallow copies of incoming and outgoing objects stored in fields.
recursively immutable
shall denote an object that is immutable and has only fields with recursively immutable content. We leave perfidious changes to the object by reflection out of the picture.

The problem with Java is, that it cannot fit immutable objects anymore into the collection framework. This gets most obvious from Collections.singletonList(). While it returns an immutable list, as the documentation says, this list can be considered broken, for the simple reason that it is immutable. Although the List interface clearly allows for operations on lists to throw an Unsupported­OperationException, this can lead to bugs which are hard to debug. The list will be passed around in the program from one place to the next and eventually some code tries to add and element to the list, because this is what one typically expects can be done with a list — booom, you get an UnsupportedOperationException out of nowwhere. And it is even an unchecked exception, to be even more surprising.

Making objects immutable by implementing an interface for mutable objects only halfway and throwing RuntimeExceptions from the mutating methods really looks like hack. Some people argue that to fix this, Java's mutable collection interfaces need to inherit from immutable ones. That would require to sneek an ImmutableCollection in as a parent interface of Collection. But looking at the Scala approach, this might not be needed. But a completely new hierarchy of immutable colletions would indeed be necessary.