This is a sentence from Java Concurrency in Practice
Shared read-only objects include immutable and effectively immutable objects.
Instances of a class that is not extensible and whose fields are all final
and themselves immutable are immutable.
Instances of a class whose fields cannot be mutated because of details of its methods are effectively immutable. For example:
final class C {
final boolean canChange;
private int x;
C(boolean canChange) { this.canChange = canChange; }
public void setX(int newX) {
if (canChange) {
this.x = newX;
} else {
throw new IllegalStateException();
}
}
}
Some instances of C
are effectively immutable and some are not.
Another example is zero-length arrays. They are effectively immutable even though their containing class is not provably immutable since there is no element of them which can be changed.
Joe-E uses a verifier to prove that some classes only allow for immutable instances. Anything marked with the Immutable marker interface are checked and certain classes like String
(effectively immutable since its char[]
does not escape) are grandfathered in as immutable.
Joe-E: A Security-Oriented Subset of Java says
The Immutable interface, defined by the Joe-E library, is treated specially by the language: the Joe-E verifier checks that every object implementing this interface will be (deeply) immutable, and raises a compile-time error if this cannot be automatically verified.