Thursday, January 13, 2005

The little nullity and a little final

Waldura writes a wonderful article on the final keyword in Java. For me also final is possibly my favorite keyword in the language. What I like best of all about it is its interaction with null. Consider this:

public class Mandatory {
    private final Law law;

    public Mandatory(final Law law) {
        if (null == law)
            throw new NullPointerException();

        this.law = law;
    }

    public Law getLaw() {
        return law;
    }
}

Here law is mandatory, that is, the class never works right without a law. Note the idiom in the constructor. Once the constructor finishes, the class is guaranteed to be null-proof: there's no setter to foul it up; the field is marked final so it won't even compile if you forget to set law in all constructors. No one calling getLaw() need ever check it for nullity. I cannot tell you how tired I get of fixing code where the author does not understand the frequent problems null generates!

And the other way with an optional field instead of mandatory as above:

public class Optional {
    private Virtue virtue;

    public Optional() {
    }

    public Optional(final Virtue virtue) {
        setVirtue(virtue);
    }

    public void setVirtue(final Virtue virtue) {
        this.virtue = virtue;
    }

    public boolean hasVirtue() {
        return null != virtue;
    }

    public Virtue getVirtue() {
        if (null == virtue)
            throw new NullPointerException();

        return virtue;
    }
}

See how much more complicated Optional is than Mandatory? Once you have optional members of a class, it drastically complicates matters. There are extra constructors (and I'm ignoring the whole notion of default values). There is the hasX()/getX() pair to catch accident use of null as early as possible. There is the setter. And we have lost the benefit of final.

The lessons? Avoid optional members (this is quite different, by the way, from the lazy evaluation idiom). Combine final with preventing nullity. The Java language encourages this with the elegance of the mandatory-field class v the clumsiness of the optional-field class.

Write elegant code, not clumsy code.

UPDATE: Reedited for clarity; too much late-night fractured grammar.

No comments: