Uses Annotation processing to generate builders for records.
- By default, Collection/Optional Types will not be null (an empty collection/optional will be provided)
- We can choose the default value of a record component in the generated builder
- Support for generating Checker/NullAway compliant builders for static null analysis.
<dependency> <groupId>io.avaje</groupId> <artifactId>avaje-record-builder</artifactId> <version>${record.version}</version> <optional>true</optional> <scope>provided</scope> </dependency>Add the annotation module as a static dependency when working with Java modules.
module my.module { requires static io.avaje.recordbuilder; }@RecordBuilder public record ArmoredCore( @DefaultValue("\"Steel Haze\"") String coreName, String model, int energyReserve, int ap) {}The following builder class will be generated for the above:
Generated Class, (click to expand)
/** Builder class for {@link ArmoredCore} */ public class ArmoredCoreBuilder { private String coreName = "Steel Haze"; private String model; private int energyReserve; private int ap; private ArmoredCoreBuilder() { }
private ArmoredCoreBuilder(String coreName, String model, int energyReserve, int ap) { this.coreName = coreName; this.model = model; this.energyReserve = energyReserve; this.ap = ap; }
/**
- Return a new builder with all fields set to default Java values */ public static ArmoredCoreBuilder builder() { return new ArmoredCoreBuilder(); }
/**
- Return a new builder with all fields set to the values taken from the given record instance */ public static ArmoredCoreBuilder builder(ArmoredCore from) { return new ArmoredCoreBuilder(from.coreName(), from.model(), from.energyReserve(), from.ap()); }
/**
- Return a new ArmoredCore instance with all fields set to the current values in this builder / public ArmoredCore build() { return new ArmoredCore(coreName, model, energyReserve, ap); } /*
- Set a new value for the {@code coreName} record component in the builder / public ArmoredCoreBuilder coreName(String coreName) { this.coreName = coreName; return this; } /*
- Set a new value for the {@code model} record component in the builder / public ArmoredCoreBuilder model(String model) { this.model = model; return this; } /*
- Set a new value for the {@code energyReserve} record component in the builder / public ArmoredCoreBuilder energyReserve(int energyReserve) { this.energyReserve = energyReserve; return this; } /*
- Set a new value for the {@code ap} record component in the builder */ public ArmoredCoreBuilder ap(int ap) { this.ap = ap; return this; } }
Using @DefaultValue we can directly write the code to set the default value in the generated builder. This allows us to directly write a value or use static methods to set the default builder state.
@RecordBuilder public record Defaults( @DefaultValue("List.of(1,2,3)") List<Integer> list, @DefaultValue("24") int num, @DefaultValue("\"string val\"") String str, @DefaultValue("CustomClass.createDefault()") CustomClass custom) {}This will generate:
public class DefaultsBuilder { private List<Integer> list = List.of(1,2,3); private int num = 24; private String str = "string val"; private CustomClass custom = CustomClass.createDefault(); ...the rest of the builder }