Bloch’s “Failure atomicity” means that if a method threw an exception, the object should still be usable afterwards. Generally, the object should be in the same state as it was before invoking the method.
In the case of an immutable object, you gain that simply from the fact that it’s immutable. There is no operation that changes the object’s state. All the methods of the object may do is create new objects that are derived from the original object.
For example, String
has a substring(int)
method. It does not change anything in the original string – it creates a new object whose content is a copy of the part of the original string that you wanted. If it throws an exception, then you simply won’t get the new object – but the original String was never changed. There is no code inside substring()
that modifies the original String
and therefore, it is failure-atomic.
Failure atomicity can be gained for mutable objects as well, but then you have to pay special attention to it, whereas in immutable objects, it simply follows from the care you took to design it to be immutable.