Search code examples
javadesign-patternsimmutabilitybuilder-pattern

Automatic generation of immutable class and matching builder class of a Java interface


What tools or libraries exists for Java that will take an interface only with accessor method definitions and automatically generate an immutable object class and also a "builder" class for incrementally building new instances or changing existing instances by creating new ones?

Example input:

public interface Car {
    String getModelName();
    int getWheelCount();
}

Example output:

import javax.annotation.concurrent.Immutable;
import javax.annotation.concurrent.NotThreadSafe;

@Immutable
public final class ImmutableCar implements Car {

    @NotThreadSafe
    public static final class Builder implements Car {

        private String modelName;
        private int wheelCount;

        public Builder() {
        }

        public Builder(final Car car) {
            modelName = car.getModelName();
            wheelCount = car.getWheelCount();
        }

        public ImmutableCar build() {
            return new ImmutableCar(wheelCount, modelName);
        }

        @Override
        public String getModelName() {
            return modelName;
        }

        @Override
        public int getWheelCount() {
            return wheelCount;
        }

        public void setModelName(final String modelName) {
            this.modelName = modelName;
        }

        public void setWheelCount(final int wheelCount) {
            this.wheelCount = wheelCount;
        }
    }

    private final String modelName;
    private final int wheelCount;

    public ImmutableCar(final int wheelCount, final String modelName) {
        this.wheelCount = wheelCount;
        this.modelName = modelName;
    }

    @Override
    public String getModelName() {
        return modelName;
    }

    @Override
    public int getWheelCount() {
        return wheelCount;
    }

}

Solution

  • Immutables (http://immutables.github.io) annotation processor is the exact match for your needs. It is full-featured and very customizable (you know all those set vs with vs no-prefix wars, - use whatever you prefer). It can generate immutable implementation with builders for interfaces, abstract classes, annotations. In addition, it can generate builders to invoke static factory methods or POJO constructors and many other things.

    @Value.Immutable
    public interface ValueObject {
      String name();
      List<Integer> counts();
      Optional<String> description();
    }
    
    // Compile using annotation processor and use it like this
    ValueObject valueObject =
       ImmutableValueObject.builder()
          .name("My value")
          .addCounts(1)
          .addCounts(2)
          .build();