In simple terms – No, this class is not immutable. But things are more complicated than that.
In his book Brian Goetz says nothing about immutable classes. He talking about immutable objects. Object called immutable if:
- its state cannot be modified after construction;
- all its fields are final;
- it's properly constructed (
this
reference doesn't escape during construction).
There is indeed no mention of final
class requirement. But this is because we are talking about objects of given type (for example Point
) at runtime. Objects can't change their type in runtime, so there is no need for final
class requirement. If we know objects state doesn't change at runtime it's effectively immutable. In this sense objects of type Point
are indeed immutable.
But note that in Listing 3.11 (Chapter 3.4 Immutablility) immutable object provided as an example, and its class defined as final
.
The problem I thinks there is some confusion between immutable object and immutable type (class).
In reality for application to be correctly multithreaded, all clients should be aligned in terms of shared objects usage policy. This is where you need immutable types. Because regardless of Point
objects immutability, there could be mutable, and as a consequence, non thread-safe Point
subtypes. And if you have any, Liskov substitution principle is broken. Point
subtypes should not degrade on provided guarantees.
For a type to be immutable it must obey following rules:
- class state cannot be modified after construction;
- all its fields are final;
- it's properly constructed (
this
reference doesn't escape during construction);
- all subtypes of a class should be immutable or class should be
final
;
- all supertypes of a class should be immutable.
This is basically same restrictions as described by Brian Goetz, but in context of compile-time rather than runtime. If you accomplish this all objects created from those immutable-types will be thread-safe.
So, write immutable classes, and yes, Point
type should be final
.