Wednesday, October 31, 2007

Immutable objects in Java

I just read a clever post from JP Moresmau on a functional language he is writing which translates to Java.

One idea which lept out at me was how to provide setters to immutable objects in Java: the setters are instance factory methods, thus:

class DontTreadOnMe {
    public final String species;
    public final int length;

    DontTreadOnMe(String species, int length) {
        this.species = species;
        this.length = length;
    }

    // Snakes can grow but cannot change species
    DontTreadOnMe setLength(int length) {
        return new DontTreadOnMe(length);
    }
}

This works rather nicely for code which uses the convention. Unfortunately, the getter/setter idea is so firmly embedded in the fingertips of Java coders, that I expect this bug frequently:

final DontTreadOnMe copperhead
        = new DontTreadOnMe("Copperhead", 1);
// Grow in length
copperhead.setLength(2);
// Oops! Does not work as expected but compiles

My preference is for the bean properties proposal. Make immutables with read-only properties; use copy-construction to make new objects with different field values (fortunately Java copy construction is vastly simpler than C++).

Post a Comment