Jerry Jalenak wrote:
So, something like this?

private String myString;

        public String getMyString()
        {
                String returnedString = this.myString;
                return (returnedString);
        }

I'm not sure how this applies to my cloning issue....


Well, String itself is immutable so it doesn't apply here. Here's the classic example from Bloch's book (p. 122):

public final class Period {
  private final Date start;
  private final Date end;

  public Period(Date start, Date end) {
    if (start.compareTo(end) > 0)
      throw new IllegalArgumentException();

    this.start = start;
    this.end = end;
  }

  public Date getStart() {
    return start;
  }

  public Date getEnd() {
    return end;
  }
}


Looks like an immutable class, right? You can set the start and end times of the Period when you create it, but once you do that, they are fixed until the class is garbage collected. The fields are final so they can't be reassigned, and there's no mutator methods to affect the fields. So fundamentally, this class is "immutable". Right?



Wrong. It's easy to overlook the fact that someone's client code can do this:


  // p is a Period instance
  Date myEnd = p.getEnd();
  myEnd.setYear(78);

It seems like I've only changed the object pointed to by "myEnd", not the object held internally by the "p" instance. Right?

Nope. Remember that both references point to the same object. So really the getter method is more like a doorway that lets me into the "immutable" Period object. The way that you make your classes truly immutable (and safe from this kind of attack) is to make a defensive copy in the getter methods. Here's how you would implement that in the Period class:

  Date getStart() {
    return new Date(this.start);
  }

  Date getEnd() {
    return new Date(this.end);
  }

This way you're only handing a *copy* of the internal data held by the Period instance.

But you're still not safe yet.

What if somehow someone had held onto a reference to one of the Date objects passed into the constructor?

  Date myEvilStart = new Date();
  Date end = new Date();
  Period p = new Period(myEvilStart, end);
  // at this point is "p" immutable?  NO!
  myEvilStart.setYear(78);
  // The "start" field in "p" has just been modified!


This lesson has been appropriated entirely from Josh Bloch's "Effective Java". If you found it useful or would like to learn more, you should get the book. 4 out of 5 dentists agree it is one of the best Java books ever written.




Erik


--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]



Reply via email to