-
Notifications
You must be signed in to change notification settings - Fork 2
Record Builder
Builders are a useful pattern that allow you to specify a set of optional parameters when creating a record, which can improve readability and reduce the need for constructor overloading.
AutoRecord provides support for generating builders using the Randgalt/record-builder library.
To enable builder generation for a given interface, simply add the @AutoRecord.Options(withBuilder = true)
annotation to it.
This will cause AutoRecord to add the @RecordBuilder
annotation to generated record and this will cause generating a builder in a next round of annotation processing.
The generated record includes a static builder()
method, which return a new builder instance.
It includes also a toBuilder()
method, which returns a builder instance with the values from the existing record.
Here's an example interface:
@AutoRecord
@AutoRecord.Options(withBuilder = true)
interface Person {
String name();
int age();
}
Here's the corresponding generated record that demonstrates builder generation:
@Generated("pl.com.labaj.autorecord.AutoRecord")
@GeneratedWithAutoRecord
@RecordBuilder
@RecordBuilder.Options(
addClassRetainedGenerated = true
)
record PersonRecord(String name, int age) implements Person {
PersonRecord {
requireNonNull(name, "name must not be null");
}
static PersonRecordBuilder builder() {
return PersonRecordBuilder.builder();
}
PersonRecordBuilder toBuilder() {
return PersonRecordBuilder.builder(this);
}
}
You can create the record instance with using builder:
PersonRecord person = PersonRecord.builder()
.name("Joe")
.age(25)
.build();
PersonRecord olderPerson = person.toBuilder()
.age(50)
.build();
It is recommended to provide in your interface:
- a factory method with a clear and descriptive name to get the record builder
- an abstract
toBuilder()
method that is implemented in the record
Here is an example of what it might look like:
@AutoRecord
@AutoRecord.Options(withBuilder = true)
interface Person {
String name();
int age();
static PersonRecordBuilder builder() {
return PersonRecord.builder();
}
PersonRecordBuilder toBuilder();
}
If you want to customize the builder generation process, you can add the RecordBuilder.Options
annotation to the interface.
Here's an example interface:
@AutoRecord
@AutoRecord.Options(withBuilder = true)
@RecordBuilder.Options(suffix = "_Creator")
interface PersonB {
String name();
int age();
}
Here's the corresponding generated record that demonstrates builder generation:
@Generated("pl.com.labaj.autorecord.AutoRecord")
@GeneratedWithAutoRecord
@RecordBuilder
@RecordBuilder.Options(
addClassRetainedGenerated = true,
suffix = "_Creator"
)
record PersonBRecord(String name, int age) implements PersonB {
PersonBRecord {
requireNonNull(name, "name must not be null");
}
static PersonBRecord_Creator builder() {
return PersonBRecord_Creator.builder();
}
PersonBRecord_Creator toBuilder() {
return PersonBRecord_Creator.builder(this);
}
}
📝 Note |
---|
It is recommended to use builder() and toBuilder() methods from an interface or generated record and not from generated builder. |
For more information, refer to the RecordBuilder library's documentation.