Friday, July 13, 2007

Immutability Is Hard

I recently coded an immutable byte array wrapper which went something like this:
public final class Bytes {

  final byte[] bytes;

  public Bytes(byte[] original) {
    int size = original.length;
    this.bytes = new byte[size];
    System.arraycopy(
        original, 0, this.bytes, 0, size);
  }

  public byte byteAt(int index) {
    return bytes[index];
  }

  public int size() {
    return bytes.length;
  }

  ...

I need to write the bytes to an OutputStream in a couple places, so I added a method which does just that:

  public void writeTo(OutputStream out)
      throws IOException {
    out.write(bytes);
  }

Did you catch my mistake?

writeTo() exposes our internal byte[] to user code making our class not so immutable. For example, zeroing out the internal bytes is now as easy as:

  Bytes bytes = ...;
  bytes.writeTo(new OutputStream() {
    @Override
    public void write(byte[] bytes) {
      Arrays.fill(bytes, 0);
    }
    ...    
  });

To make our class immutable again, we must modify writeTo() to copy the bytes into a temporary buffer first, and then pass that buffer to the OutputStream.

It's times like this that I wish Java had immutable arrays (with runtime checking). Maybe I'll see what we can do about that...

Thursday, July 12, 2007

Dick is at it again...

This time he's squeezing more Guice out of his tests with EasyMock. Dick, you sick bastard.

I think I've been reading too much FSJ.

Tuesday, July 10, 2007

Guice: Java's Missing Features

Do you have trouble testing your Java code? I'm not afraid to admit that I used to. For a long time, I blamed myself and wondered what I was doing wrong. Eventually, I learned that the problems lied with Java the language, not my skills or understanding. You can bet James Gosling didn't have unit testing in mind back when he first designed Java.

Until we fix the language or something better comes along, Guice can work with Java to resolve some of the issues. Jesse Wilson, who you may know as the creator of Glazed Lists, has posted parts one and two of an N part series dedicated to using Guice to fix a vanilla, static-clung Java application. Jesse has a lot of experience refactoring legacy code. I'm glad he's sharing his wisdom.