hiwa wrote On 03/07/06 04:36,:
I used to be uneasy at the fact that immutability
of a class object is only casually mentioned in
some tiny corner of the API documentation.
And I wonder why we can't do:
public immutable class BigDecimal
or, implementing a marker inteface:
public class BigDecimal
All Implemented Interfaces:
Immutable, Serializable, Comparable<BigDecimal>
Probably because "immutable" can be hard to pin down
satisfactorily. Example:
final class ImmutableThing {
// these members are assumed immutable, too:
private final SomeThing x;
private final OtherThing y;
private final ThirdThing z;
ImmutableThing() {
x = new SomeThing("surprise");
y = new OtherThing("fear");
z = new ThirdThing("there is no third thing");
}
public boolean equals(Object obj) {
if (! (obj instanceof ImmutableThing))
return false;
ImmutableThing that = (ImmutableThing)obj;
return x.equals(that.x) && y.equals(that.y)
&& z.equals(that.z);
}
private int lazyHash; // computed only if needed
public int hashCode() {
if (lazyHash == 0) {
// do the expensive hashing only once
laxyHash = x.hashCode() ^ y.hashCode()
^ z.hashCode();
}
return lazyHash;
}
}
The crucial question: Is this class immutable? One
argument says it's not, because the lazyHash member's value
can change after construction. Another argument says that
doesn't matter, because lazyHash can only be observed by
calling hashCode() and hashCode() returns a constant value.
Both are right, in their own terms -- and how are you going
to define the semantics of a keyword or marker interface so
as to make both sides happy? If you can't, how will you
placate those on the unhappy side?
There's quite a lot about Java that lives solely in the
documentation. For instance, the compiler would accept
class Stupid implements Comparable {
public int compareTo(Object obj) {
return 42;
}
}
Only the JavaDoc tells us that this does not fulfill the
contract of the Comparable interface; the compiler is not
aware of the contract and so cannot enforce it. Immutabilty
(both the quality itself and the sense in which it is to be
understood for the class at hand) is a similar case. Or as
a colleague once observed, "The compiler is not a substitute
for self-discipline."