The purpose of this project is to provide the Java Community with the opportunity to test drive and comment on a method of incorporating immutability into the Java Development Kit.

However, as the most important parts of the idea cannot be easily tested, due to the necessity of two new keywords being added to the Java Language Specification, we can only show what the code would look like, by using in-line comments.

For example:


// public immutable class ImmutableData {
public class ImmutableData implements Immutable {
    public final int id;
    public final String name;
    public /* final lazy */ int hash; /* = hash(); */ // Method call not made until variable is referenced
    public /* final lazy */ boolean done;
    public /* final lazy */ boolean tested;

    public ImmutableData(final String name, final int id){
        this.name = name;
        this.id = id;
    }

    public int hashCode(){
        return hash;
    }

    private /* lazy */ int hash(){
        int h = 7;
        h = 31 * h + name.hashCode();
        return h;
    }

    public final /* lazy */ void setDone(){
        done = true;
    }

    public void test(){
        // Test code ...
        setTested();
    }

    private /* lazy */ void setTested(){
        tested = true;
    }
}
                

The two keywords are: immutable and lazy.

immutable

This is a class modifier which would be used to both designate a class as being immutable, and forcing the use of the final keyword for all instance variables.

lazy

This is both an instance variable modifier, and a non-static method modifier.

As an instance variable modifier, it would only be used in conjunction with the final modifier, as in the example above. Its purpose, is to allow the variable to be set to its final value, at some time after the object has been instantiated. An ideal example would be the hash variable inside the java.lang.String class. As it doesn't get set, unless and until it is required, this could not simply be set to final.

As a non-static method modifier, it would only be used to designate a method that was setting the final value for a lazy variable of the same name (using the setXXXXX() naming convention, see example above). For private methods, only use lazy. For all other methods, use final lazy. Whether or not these methods should be open to being parameterized, is another point for discussion.

Note:

In addition to the above keywords,


    private void readObject(java.io.ObjectInputStream s)
                

should be treated as a class constructor, in relation to setting final instance variables, during deserialization.