### User Class with Private Constructor and Inner Builder Source: https://github.com/skinny85/jilt/blob/master/Readme.md Example of a User class with a private constructor, forcing instantiation through a static builder method. The InnerBuilder extends the generated UserBuilder to call the private constructor. ```java import org.jilt.Builder; import org.jilt.BuilderStyle; import org.jilt.Opt; public final class User { public final String email, username, firstName, lastName, displayName; @Builder(style = BuilderStyle.STAGED, toBuilder = "toBuilder") private User(String email, @Opt String username, String firstName, String lastName, @Opt String displayName) { this.email = email; this.username = username == null ? email : username; this.firstName = firstName; this.lastName = lastName; this.displayName = displayName == null ? firstName + " " + lastName : displayName; } private static final class InnerBuilder extends UserBuilder { @Override public User build() { return new User(email, username, firstName, lastName, displayName); } } public static UserBuilders.Email builder() { return new InnerBuilder(); } public UserBuilder toBuilder() { return UserBuilder.toBuilder(new InnerBuilder(), this); } } ``` -------------------------------- ### Functional toBuilder() Method Usage Source: https://github.com/skinny85/jilt/blob/master/Readme.md Use the `toBuilder()` method (aliased as `copy` in this example) to create a new instance based on an existing one, with the ability to override properties. All properties are considered optional in this context. ```java import static example.UserBuilder.email; import static example.UserBuilder.firstName; import static example.UserBuilder.lastName; import static example.UserBuilder.Optional.displayName; User user = UserBuilder.user( email("jd@example.com"), firstName("John"), lastName("Doe") ); User copy = UserBuilder.copy(user, lastName("Johnson"), // a single required property is allowed here displayName("Johnny J") // optional properties are also allowed here ); ``` -------------------------------- ### Example of a required property in STAGED Builder Source: https://github.com/skinny85/jilt/blob/master/Readme.md Illustrates client code using a STAGED builder where 'username' is a required property. This code will break if 'username' is later changed to optional without using STAGED_PRESERVING_ORDER. ```java User user = UserBuilder.user() .email("jd@example.com") .username("johnnyd") // username() has to be called here, as it's not optional .firstName("John") .lastName("Doe") .build(); ``` -------------------------------- ### Generate Builder for a Java Class Source: https://github.com/skinny85/jilt/blob/master/Readme.md Annotate a class with @Builder to automatically generate its corresponding Builder class. This example shows a simple Person class. ```java import org.jilt.Builder; @Builder public final class Person { public final String name; public final boolean isAdult; public Person(String name, boolean isAdult) { this.name = name; this.isAdult = isAdult; } } ``` ```java public class PersonBuilder { public static PersonBuilder person() { return new PersonBuilder(); } private String name; private boolean isAdult; public PersonBuilder name(String name) { this.name = name; return this; } public PersonBuilder isAdult(boolean isAdult) { this.isAdult = isAdult; return this; } public Person build() { return new Person(name, isAdult); } } ``` -------------------------------- ### Building a User with STAGED_PRESERVING_ORDER Source: https://github.com/skinny85/jilt/blob/master/Readme.md Demonstrates how to use the generated builder for the User class with STAGED_PRESERVING_ORDER. Required properties must be set in their defined order, while optional properties are also placed in their original order. ```java User user = UserBuilder.user() .email("jd@example.com") // this has to be 'email' to compile - required property .username("johnnyd") // this will always be where username is set, regardless whether it's required or optional .firstName("John") // this has to be 'firstName' to compile - required property .lastName("Doe") // this has to be 'lastName' to compile - required property .displayName("Johnny D") // this will always be where displayName is set, regardless whether it's required or optional .build(); ``` -------------------------------- ### Reusable Builder Configuration with Meta-Annotations Source: https://context7.com/skinny85/jilt/llms.txt Define common builder configurations once using a meta-annotation. Apply this meta-annotation to classes or constructors to reuse settings like style, setter prefix, and factory method name. ```java import org.jilt.Builder; import org.jilt.BuilderInterfaces; import org.jilt.BuilderStyle; // Define the meta-annotation once: @Builder(style = BuilderStyle.STAGED, setterPrefix = "with", factoryMethod = "builder", className = "*JiltBuilder") @BuilderInterfaces(lastInnerName = "Meta") public @interface MetaBuilder {} ``` ```java // Apply to any number of classes / constructors: public class OrderLine { public final String sku; public final int qty; @MetaBuilder public OrderLine(String sku, int qty) { this.sku = sku; this.qty = qty; } } ``` ```java // Jilt generates OrderLineJiltBuilder with setterPrefix "with" and factory "builder": OrderLine line = OrderLineJiltBuilder.builder() .withSku("ABC-123") .withQty(5) .build(); ``` -------------------------------- ### Use Functional Builder to Create User Instance Source: https://github.com/skinny85/jilt/blob/master/Readme.md Instantiate a User object using the generated functional builder. Required parameters are passed directly, while optional parameters are accessed via the Optional nested class. ```java User user = UserBuilder.user( UserBuilder.email("jd@example.com"), // this is required UserBuilder.firstName("John"), // this is required UserBuilder.lastName("Doe"), // this is required UserBuilder.Optional.username("johnnyd") // this is optional ); ``` -------------------------------- ### Concise Functional Builder Usage with Static Imports Source: https://github.com/skinny85/jilt/blob/master/Readme.md Leverage Java's static imports to simplify the syntax when using the functional builder, making the instantiation more readable. ```java import static example.UserBuilder.email; import static example.UserBuilder.firstName; import static example.UserBuilder.lastName; import static example.UserBuilder.user; import static example.UserBuilder.Optional.username; User user = user( email("jd@example.com"), // this is required firstName("John"), // this is required lastName("Doe"), // this is required username("johnnyd") // this is optional ); ``` -------------------------------- ### Abstract Builder with Private Constructor Source: https://context7.com/skinny85/jilt/llms.txt Use when the builder is the only way to instantiate a class. Requires extending the generated abstract builder and providing a static factory method. ```java import org.jilt.Builder; import org.jilt.BuilderStyle; import org.jilt.Opt; public final class UserPriv { public final String email, username, firstName, lastName, displayName; @Builder(style = BuilderStyle.STAGED, toBuilder = "toBuilder") private UserPriv(String email, @Opt String username, String firstName, String lastName, @Opt String displayName) { this.email = email; this.username = username == null ? email : username; this.firstName = firstName; this.lastName = lastName; this.displayName = displayName == null ? firstName + " " + lastName : displayName; } private static final class InnerBuilder extends UserPrivBuilder { @Override public UserPriv build() { return new UserPriv(email, username, firstName, lastName, displayName); } } public static UserPrivBuilders.Email builder() { return new InnerBuilder(); } public UserPrivBuilder toBuilder() { return UserPrivBuilder.toBuilder(new InnerBuilder(), this); } } ``` ```java // Only way to create UserPriv is through the builder: UserPriv user = UserPriv.builder() .email("user@example.com") .firstName("Alice") .lastName("Smith") .build(); ``` ```java // Copy with changes: UserPriv modified = user.toBuilder() .lastName("Jones") .build(); // modified.email == "user@example.com", modified.lastName == "Jones" ``` -------------------------------- ### Using Staged Builder with Optional Properties Source: https://github.com/skinny85/jilt/blob/master/Readme.md Construct an object using a Staged Builder, providing only the required properties and optionally setting values for properties marked with @Opt. ```java User user = UserBuilder.user() .email("jd@example.com") // this has to be 'email' to compile .firstName("John") // this is not 'username', because that is an optional property .lastName("Doe") // this has to be 'lastName' to compile .displayName("Johnny D") // this could be 'username', or skipped .build(); ``` -------------------------------- ### Abstract Base Class with Abstract Builder Method Source: https://github.com/skinny85/jilt/blob/master/Readme.md Demonstrates using @Builder on an abstract method within an abstract base class. Subclasses extend the generated base builder and override the build() method to instantiate their specific subclass. ```java abstract class JiltContext { @Builder(className = "SomeBaseClassBuilder", packageName = "my.package") abstract T produceInstance( String prop1, int prop2, boolean prop3, ...); } class Subclass1 extends SomeBaseClass { static class Subclass1Builder extends SomeBaseClassBuilder { @Override public Subclass1 build() { return new Subclass1(this.prop1, this.prop2, this.prop3, ...); } } // ... } class Subclass2 extends SomeBaseClass { static class Subclass2Builder extends SomeBaseClassBuilder { @Override public Subclass2 build() { return new Subclass2(this.prop1, this.prop2, this.prop3, ...); } } // ... } ``` -------------------------------- ### Define toBuilder Instance Method on Target Class Source: https://github.com/skinny85/jilt/blob/master/Readme.md Implement a `toBuilder` instance method on the target class that delegates to the static builder method for convenience. This allows creating copies directly from an object instance. ```java public final class User { // ... public User copy(UserBuilders.Setter... setters) { return UserBuilder.copy(this, setters); } } ``` -------------------------------- ### Generate Builder with @Builder on Class (Classic Style) Source: https://context7.com/skinny85/jilt/llms.txt Apply the `@Builder` annotation to a class to generate a standard fluent Builder. Jilt uses instance fields and expects a matching all-args constructor. Properties can be set in any order, and setter calls are chainable. ```java import org.jilt.Builder; import java.util.List; @Builder public class ClassicValue { private final String name; private final int age; private final String nick; private final List securityAnswers; public ClassicValue(String name, int age, String nick, List securityAnswers) { this.name = name; this.age = age; this.nick = nick; this.securityAnswers = securityAnswers; } // getters omitted for brevity } // Usage — Jilt generates ClassicValueBuilder: ClassicValue value = ClassicValueBuilder.classicValue() // static factory method .name("Alice") .age(30) .nick("ali") .securityAnswers(List.of("Cat", "London")) .build(); // Properties can be set in any order; setter calls are chainable: ClassicValue value2 = new ClassicValueBuilder() // direct instantiation also works .nick("placeholder") .name("Bob") .nick("bobby") // last setter call wins .age(25) .securityAnswers(List.of("Dog")) .build(); ``` -------------------------------- ### Generate Builder with Lombok Integration Source: https://github.com/skinny85/jilt/blob/master/Readme.md Jilt seamlessly integrates with Lombok. Annotate a Lombok data class with @Builder to generate its Builder. ```java import org.jilt.Builder; import lombok.Data; @Builder @Data public final class Person { private final String name; private final boolean isAdult; } ``` -------------------------------- ### Apply Custom Meta-Annotation to a Class Source: https://github.com/skinny85/jilt/blob/master/Readme.md Apply a custom meta-annotation to a class to inherit its builder configuration. This is equivalent to annotating the class with the meta-annotation's underlying @Builder and @BuilderInterfaces. ```java @MyBuilder // uses @Builder and @BuilderInterfaces values from @MyBuilder public final class MyValueClass { // ... } ``` -------------------------------- ### User Class with STAGED_PRESERVING_ORDER Builder Source: https://github.com/skinny85/jilt/blob/master/Readme.md Defines a User class using the STAGED_PRESERVE_ORDER builder style. Note the use of @Opt for optional properties like 'username' and 'displayName'. ```java import org.jilt.Builder; import org.jilt.BuilderStyle; import org.jilt.Opt; public final class User { public final String email, username, firstName, lastName, displayName; @Builder(style = BuilderStyle.STAGED_PRESERVING_ORDER) public User(String email, @Opt String username, String firstName, String lastName, @Opt String displayName) { this.email = email; this.username = username == null ? email : username; this.firstName = firstName; this.lastName = lastName; this.displayName = displayName == null ? firstName + " " + lastName : displayName; } } ``` -------------------------------- ### Configure Builder Class Name with Meta-Annotation Source: https://github.com/skinny85/jilt/blob/master/Readme.md Define a meta-annotation to customize the generated builder class name using a wildcard. The '*' character is replaced with the name of the class being built. ```java import org.jilt.Builder; @Builder(className = "*JiltBuilder") public @interface MyBuilder { } ``` -------------------------------- ### Define User Class for Functional Builder Source: https://github.com/skinny85/jilt/blob/master/Readme.md Annotate the constructor with @Builder(style = BuilderStyle.FUNCTIONAL, toBuilder = "copy") to enable the functional builder style. Use @Opt for optional parameters. ```java package example; public final class User { public final String email, username, firstName, lastName, displayName; @Builder(style = BuilderStyle.FUNCTIONAL, toBuilder = "copy") public User(String email, @Opt String username, String firstName, String lastName, @Opt String displayName) { this.email = email; this.username = username == null ? email : username; this.firstName = firstName; this.lastName = lastName; this.displayName = displayName == null ? firstName + " " + lastName : displayName; } } ``` -------------------------------- ### Define Custom Builder Meta-Annotation Source: https://github.com/skinny85/jilt/blob/master/Readme.md Use @Builder and @BuilderInterfaces to define a reusable meta-annotation for builder configurations. This avoids repeating annotations across multiple classes. ```java import org.jilt.Builder; import org.jilt.BuilderInterfaces; import org.jilt.BuilderStyle; @Builder(style = BuilderStyle.STAGED, setterPrefix = "set", buildMethod = "create") @BuilderInterfaces(innerNames = "B_*") public @interface MyBuilder { } ``` -------------------------------- ### Builder on Static Method Source: https://github.com/skinny85/jilt/blob/master/Readme.md Place the @Builder annotation on a static method to generate a builder. The method's return type is the built class, and its parameters become the builder properties. The instance is created by calling this method, allowing for custom construction logic. ```java import org.jilt.Builder; import java.util.Date; public abstract class DateFactory { @Builder(packageName = "com.example") public static Date make(int month, int day, int year) { // validation if (month < 1 || month > 12) { throw new IllegalArgumentException("month must be between 1 and 12"); } // default value if (day == 0) { day = 1; } // non-standard construction return new Date(year + 1900, month - 1, day); } } ``` ```java import com.example.DateBuilder; import org.junit.Assert; import org.junit.Test; import java.util.Date; public class DateFactoryTest { @Test public void use_date_builder() { Date date = DateBuilder.date() .month(12) .year(23) .build(); Assert.assertEquals(11, date.getMonth()); Assert.assertEquals(1, date.getDay()); Assert.assertEquals(1923, date.getYear()); } } ``` -------------------------------- ### Builder on Constructor Source: https://github.com/skinny85/jilt/blob/master/Readme.md Use the @Builder annotation on a constructor to generate a builder where properties correspond to constructor parameters. The instance is created by calling this constructor. ```java import org.jilt.Builder; public final class Person { public final String name; public final boolean isAdult; private int thisFieldWillBeIgnoredByTheBuilder; @Builder public Person(String name, boolean isAdult) { this.name = name; this.isAdult = isAdult; } } ``` -------------------------------- ### Builder Generation for Java Records with @Builder Source: https://context7.com/skinny85/jilt/llms.txt Jilt supports Java 14+ records directly. Apply `@Builder` to the record or its compact constructor to generate builder methods, including `toBuilder` support. ```java import org.jilt.Builder; import org.jilt.BuilderStyle; import org.jilt.Opt; @Builder(style = BuilderStyle.STAGED, toBuilder = "copy") public record RecordNoWorkaround(@Opt String name, int age) {} // Build: RecordNoWorkaround rec = RecordNoWorkaroundBuilder.recordNoWorkaround() .age(23) // name is optional — skipped here .build(); // rec.name() == null, rec.age() == 23 // toBuilder copy: RecordNoWorkaround updated = RecordNoWorkaroundBuilder.copy(rec) .age(-1) .build(); // updated.name() == null (preserved), updated.age() == -1 ``` -------------------------------- ### Staged Builder Pattern Source: https://github.com/skinny85/jilt/blob/master/Readme.md Configure a staged builder by setting `style = BuilderStyle.STAGED` in the @Builder annotation. This enforces a specific order for initializing builder properties through generated interfaces, ensuring all steps are completed before building the instance. ```java import org.jilt.Builder; import org.jilt.BuilderStyle; @Builder(style = BuilderStyle.STAGED) public final class Person { public final String name; public final boolean isAdult; public Person(String name, boolean isAdult) { this.name = name; this.isAdult = isAdult; } } ``` ```java Person person = PersonBuilder.person() .name("John Doe") // this has to be 'name' for the code to compile .isAdult(true) // this has to be 'isAdult' for the code to compile .build(); // this has to be 'build' for the code to compile ``` -------------------------------- ### Gradle Dependency for Jilt Source: https://context7.com/skinny85/jilt/llms.txt Configure Gradle to include Jilt as a compile-only and annotation processor dependency. Ensure the mavenCentral repository is declared. ```groovy repositories { mavenCentral() } dependencies { compileOnly("cc.jilt:jilt:1.9.1") annotationProcessor("cc.jilt:jilt:1.9.1") } ``` -------------------------------- ### Marking Optional Properties with @Opt and @Nullable Source: https://context7.com/skinny85/jilt/llms.txt Use @Opt or any @Nullable annotation to mark fields or parameters as optional in the generated builder. Optional properties can be omitted during object creation. ```java import org.jilt.Builder; import org.jilt.BuilderStyle; import org.jilt.Opt; import javax.annotation.Nullable; public final class Article { public final String title; public final String body; public final String subtitle; // optional public final String author; // optional via @Nullable @Builder(style = BuilderStyle.STAGED) public Article(String title, @Opt String subtitle, String body, @Nullable String author) { this.title = title; this.subtitle = subtitle; this.body = body; this.author = author; } } // subtitle and author are optional — both appear in the Optionals interface: Article article = ArticleBuilder.article() .title("Jilt Guide") .body("Jilt generates builders...") .subtitle("A practical introduction") // optional — can be omitted .build(); // article.author == null (zero-value default) ``` -------------------------------- ### Generate Builder for a Java Record Source: https://github.com/skinny85/jilt/blob/master/Readme.md Jilt also supports generating Builders for Java records. Annotate the record with @Builder. ```java import org.jilt.Builder; @Builder public record Person(String name, boolean isAdult) { } ``` -------------------------------- ### Generating a Copy/Modify Builder with @Builder.toBuilder Source: https://context7.com/skinny85/jilt/llms.txt Set `toBuilder` attribute on `@Builder` to generate a static method that initializes a new builder from an existing instance, allowing for easy copying and modification. ```java import org.jilt.Builder; import org.jilt.BuilderStyle; public class Config { public final String host; public final int port; public final boolean ssl; @Builder(style = BuilderStyle.CLASSIC, toBuilder = "fromConfig") public Config(String host, int port, boolean ssl) { this.host = host; this.port = port; this.ssl = ssl; } } Config base = ConfigBuilder.config() .host("localhost").port(5432).ssl(false).build(); // Create a modified copy — only override what changed: Config prod = ConfigBuilder.fromConfig(base) .host("db.prod.example.com") .ssl(true) .build(); // prod.port == 5432 (copied from base), prod.host == "db.prod.example.com" ``` -------------------------------- ### Generate Builder with @Builder on Static Factory Method Source: https://context7.com/skinny85/jilt/llms.txt Annotate a static method with `@Builder` to generate a Builder for classes you cannot modify. The generated Builder's `build()` method will invoke the annotated static method. You can specify a package name for the generated builder. ```java import org.jilt.Builder; import java.util.Date; public abstract class DateFactory { @Builder(packageName = "com.example") public static Date make(int month, int day, int year) { if (month < 1 || month > 12) throw new IllegalArgumentException("month must be 1-12"); if (day == 0) day = 1; // default value logic return new Date(year + 1900, month - 1, day); } } // Usage — Jilt generates com.example.DateBuilder: import com.example.DateBuilder; Date date = DateBuilder.date() .month(12) .year(23) // day intentionally omitted → defaults to 1 .build(); // date.getMonth() == 11 (0-indexed), date.getDay() == 1, date.getYear() == 1923 ``` -------------------------------- ### Generic Class Support in Jilt Builders Source: https://context7.com/skinny85/jilt/llms.txt Jilt propagates type parameters from generic target classes to their generated Builders. The generated builder will also be generic. ```java import org.jilt.Builder; @Builder public class Generic1TypeParam { public final T t; public Generic1TypeParam(T t) { this.t = t; } } ``` ```java // The generated Generic1TypeParamBuilder is itself generic: Generic1TypeParam strBox = Generic1TypeParamBuilder.generic1TypeParam() .t("hello") .build(); Generic1TypeParam intBox = Generic1TypeParamBuilder.generic1TypeParam() .t(42) .build(); ``` -------------------------------- ### STAGED Builder Style for Type-Safe Step Building Source: https://context7.com/skinny85/jilt/llms.txt Use BuilderStyle.STAGED to enforce that all required properties are set in the correct order at compile time. Jilt generates interfaces for each required property and a final Optionals interface for optional properties. ```java import org.jilt.Builder; import org.jilt.BuilderStyle; import org.jilt.Opt; public final class User { public final String email, username, firstName, lastName, displayName; @Builder(style = BuilderStyle.STAGED, toBuilder = "modifiedUser") public User(String email, @Opt String username, String firstName, String lastName, @Opt String displayName) { this.email = email; this.username = username == null ? email : username; this.firstName = firstName; this.lastName = lastName; this.displayName = displayName == null ? firstName + " " + lastName : displayName; } } // Jilt generates UserBuilder + UserBuilders interface hierarchy. // The compiler forces: email → firstName → lastName → [optionals] → build() User user = UserBuilder.user() .email("jd@example.com") // must be first — returns UserBuilders.FirstName .firstName("John") // username is skipped (optional) .lastName("Doe") // returns UserBuilders.Optionals .displayName("Johnny D") // optional — can be omitted .username("johnnyd") // optional — can be omitted .build(); // toBuilder — create a modified copy pre-initialized from an existing instance: User modified = UserBuilder.modifiedUser(user) .firstName("Jane") .build(); // modified.email == "jd@example.com", modified.firstName == "Jane" ``` -------------------------------- ### STAGED_PRESERVING_ORDER Builder Style for Backwards Compatibility Source: https://context7.com/skinny85/jilt/llms.txt Use BuilderStyle.STAGED_PRESERVING_ORDER for a staged builder that maintains backwards compatibility. Optional properties retain their original declaration position, preventing build breaks when properties become optional. ```java import org.jilt.Builder; import org.jilt.BuilderStyle; import org.jilt.Opt; public final class FullName { public final String firstName, middleName, lastName; @Builder(style = BuilderStyle.STAGED_PRESERVING_ORDER) public FullName(String firstName, @Opt String middleName, String lastName) { this.firstName = firstName; this.middleName = middleName; this.lastName = lastName; } } // middleName is optional but always settable at its original position: FullName withMiddle = FullNameBuilder.fullName() .firstName("William") .middleName("H") // optional — can be skipped .lastName("Macy") .build(); FullName withoutMiddle = FullNameBuilder.fullName() .firstName("William") // middleName() call skipped — goes directly to lastName() .lastName("Macy") .build(); ``` -------------------------------- ### Define Optional Properties with @Opt Source: https://github.com/skinny85/jilt/blob/master/Readme.md Use the @Opt annotation on fields or constructor parameters to mark them as optional in Staged Builders. If an optional property is not set, Jilt uses its zero-value. ```java import org.jilt.Builder; import org.jilt.BuilderStyle; import org.jilt.Opt; public final class User { public final String email, username, firstName, lastName, displayName; @Builder(style = BuilderStyle.STAGED) public User(String email, @Opt String username, String firstName, String lastName, @Opt String displayName) { this.email = email; this.username = username == null ? email : username; this.firstName = firstName; this.lastName = lastName; this.displayName = displayName == null ? firstName + " " + lastName : displayName; } } ``` -------------------------------- ### FUNCTIONAL Builder Style for Named-Parameter Syntax Source: https://context7.com/skinny85/jilt/llms.txt Use BuilderStyle.FUNCTIONAL for a named-parameter style builder, best utilized with Java static imports. It generates a static factory method with single-method interfaces for each property. ```java import org.jilt.Builder; import org.jilt.BuilderStyle; import org.jilt.Opt; public final class UserFunc { public final String email, username, firstName, lastName, displayName; @Builder(style = BuilderStyle.FUNCTIONAL, toBuilder = "copy") private UserFunc(String email, @Opt String username, String firstName, String lastName, @Opt String displayName) { this.email = email; this.username = username == null ? email : username; this.firstName = firstName; this.lastName = lastName; this.displayName = displayName == null ? firstName + " " + lastName : displayName; } // private constructor + inner builder pattern for full encapsulation (see below) } // With static imports — reads like named parameters: import static example.UserFuncBuilder.email; import static example.UserFuncBuilder.firstName; import static example.UserFuncBuilder.lastName; import static example.UserFuncBuilder.Optional.username; import static example.UserFuncBuilder.Optional.displayName; UserFunc user = UserFunc.userFunc( email("jd@example.com"), // required firstName("John"), // required lastName("Doe"), // required username("johnnyd"), // optional displayName("Johnny D") // optional ); // Functional toBuilder — copy with overrides: UserFunc copy = user.copy( lastName("Johnson"), displayName("Johnny J") ); // copy.email == "jd@example.com", copy.lastName == "Johnson" ``` -------------------------------- ### Generate Builder with @Builder on Constructor Source: https://context7.com/skinny85/jilt/llms.txt Annotate a specific constructor with `@Builder` to precisely control which parameters become Builder properties. This is useful for classes with multiple constructors or computed fields. ```java import org.jilt.Builder; public final class Person { public final String name; public final boolean isAdult; @Builder public Person(String firstName, String lastName, int age) { this.name = firstName + " " + lastName; this.isAdult = age >= 18; } } // Jilt generates PersonBuilder with properties firstName, lastName, age: Person person = PersonBuilder.person() .firstName("Jane") .lastName("Doe") .age(22) .build(); // person.name == "Jane Doe" // person.isAdult == true ``` -------------------------------- ### Maven Dependency for Jilt Source: https://github.com/skinny85/jilt/blob/master/Readme.md Add Jilt as a 'provided' scope dependency in your Maven project. It is not needed at runtime. ```xml cc.jilt jilt 1.9.1 provided ``` -------------------------------- ### Maven Dependency for Jilt Source: https://context7.com/skinny85/jilt/llms.txt Add Jilt as a compile-only annotation processor dependency. No runtime dependency is needed. ```xml cc.jilt jilt 1.9.1 provided ``` -------------------------------- ### Exclude Fields from Builder with @Builder.Ignore Source: https://context7.com/skinny85/jilt/llms.txt Mark a field with `@Builder.Ignore` to prevent it from being included as a property in the generated Builder when `@Builder` is applied to the class. The field will not have a corresponding setter method in the Builder. ```java import org.jilt.Builder; @Builder public class IgnoreValue { public final String str; @Builder.Ignore // this field will NOT appear as a Builder property public final char chr = '\n'; public final long lng; public IgnoreValue(String str, long lng) { this.str = str; this.lng = lng; } } // Generated IgnoreValueBuilder only exposes str() and lng(): IgnoreValue v = IgnoreValueBuilder.ignoreValue() .str("hello") .lng(42L) .build(); ``` -------------------------------- ### Customizing Generated Interfaces with @BuilderInterfaces Source: https://context7.com/skinny85/jilt/llms.txt Use @BuilderInterfaces alongside @Builder in Staged or Functional styles to rename the outer builder interface, individual per-property interfaces, and the final build-bearing interface. ```java import org.jilt.Builder; import org.jilt.BuilderInterfaces; import org.jilt.BuilderStyle; import org.jilt.Opt; @Builder(style = BuilderStyle.STAGED, setterPrefix = "with", buildMethod = "create") @BuilderInterfaces( outerName = "PersonSteps", // default would be PersonBuilders innerNames = "Step_*", // Step_Name, Step_Age, … lastInnerName = "BuildStep" // interface containing create() ) public final class Person { public final String name; public final int age; public Person(String name, @Opt int age) { this.name = name; this.age = age; } } // The generated interfaces are PersonSteps.Step_Name, PersonSteps.BuildStep, etc.: Person p = PersonBuilder.person() .withName("Alice") // setterPrefix = "with" .create(); // buildMethod = "create" ``` -------------------------------- ### Excluding Jilt-Generated Code from Coverage Reports Source: https://context7.com/skinny85/jilt/llms.txt Jilt annotates all generated Builder classes with `@JiltGenerated`. Configure code coverage tools like JaCoCo to automatically exclude these classes from reports. ```java // In your JaCoCo configuration (build.gradle): jacocoTestReport { afterEvaluate { classDirectories.setFrom(files(classDirectories.files.collect { fileTree(dir: it, exclude: [ // Exclude classes annotated with @JiltGenerated via a custom exclusion rule, // or configure JaCoCo's @ExcludeFromJacocoGeneratedReport support. // JaCoCo 0.8.2+ respects any annotation whose simple name is "Generated". // Jilt also emits javax.annotation.processing.Generated (Java 9+), // so no extra configuration is typically needed. ]) })) } } // No source-level action needed — @JiltGenerated is applied automatically to every // Builder class Jilt generates: // @JiltGenerated // public class PersonBuilder { ... } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.