[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: the benefits of immutability

On Dienstag, August 19, 2003, at 06:58  Uhr, Vadim Nasardinov wrote:

> Pascal Costanza wrote:
> > What's the problem with this?
> >
> > public boolean equals(Object obj) {
> >   if (!(obj instanceof Subclass)) return false;
> >
> >   Subclass that = (Subclass)obj;
> >
> >   return super.equals(that) && (this.m_num == that.m_num);
> > }
> With the Subclass defining its equals method the way suggested above,
> the Superclass's equals method is no longer symmetric, thus violating
> the method's documented contract.  See the example at the bottom of
> this message.

You're right. Here is one addition that should do the job, provided 
that all involved equals definitions are implemented along these lines:

public boolean equals(Object that) {
   if ((this.class != that.class) &&
     return that.equals(this);

   if (!(that instanceof Subclass)) return false;

   return super.equals(that) && (this.state == ((Subclass)that).state);

> Immutability doesn't mean that the
> underlying representation does not change, once the instance has been
> constructed.  Rather, it means that none of the visible state ever
> changes it if is accessible via the exported API.  For instance, if
> you call str.substring(10), you always get the same result back.  If
> you allow subclassing, then the compiler cannot enforce this
> requirement in all but the simplest cases.  Sure if the class is
> declared "immutable" (where "immutable" is a new hypothetical Java
> keyword), then the compiler can enforce the requirement that all
> instance fields be "final".  So far, so good.  However, the compiler
> cannot enforce the requirement that the substring method of the String
> type always return the same value, if subclassing is allowed.

Sure, but neither can the compiler enforce that requirement if 
subclassing is not allowed. The enforcement of that requirement is not 
related to subclassing.

An immutable class modifier could at least help to make the intentions 
clear, and provide some guarantees. Furthermore, the compiler and/or 
runtime system could exploit that declaration. Any violation would be 
regarded as a programming error that can, for example, be caught by 
proper unit testing.