Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Lombok Instance Copy: Can You Use Builder?

Learn how to copy a Lombok parent instance into a child using builder. See if Lombok can do it without manual field copying.
Illustration of Lombok's @Builder attempting to copy superclass data to a subclass in Java, highlighting inheritance challenges. Illustration of Lombok's @Builder attempting to copy superclass data to a subclass in Java, highlighting inheritance challenges.
  • 🔍 Lombok’s @Builder does not automatically copy instance data from a superclass to a subclass.
  • 🏗️ Developers must manually define custom builder methods or constructors to transfer inherited properties.
  • 🛠️ Using alternative libraries like MapStruct or ModelMapper can simplify instance copying in complex hierarchies.
  • 📏 Best practices suggest preferring constructors and considering composition over deep inheritance for better maintainability.
  • ⚡ While Lombok streamlines object creation, it lacks built-in support for handling Java inheritance seamlessly.

Understanding Lombok’s @Builder and Instance Copying Across Inheritance

Lombok is a powerful Java library that significantly reduces boilerplate code, making development more efficient. Among its most useful features is @Builder, which simplifies object creation by providing an easy-to-use builder pattern. However, when dealing with Java inheritance, an important question arises: Can Lombok's builder efficiently copy an instance from a superclass to a subclass? This article explores whether Lombok natively supports such functionality, its inherent limitations, and practical workarounds that Java developers can use.

How Lombok’s @Builder Works

Lombok’s @Builder annotation allows developers to create immutable objects using a builder pattern, making it easier to handle objects with multiple parameters while improving readability and maintainability.

Basic Usage of Lombok’s @Builder

Consider the following simple implementation:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

@Builder
public class Person {
    private String name;
    private int age;
}

This allows object instantiation with a clean and readable syntax:

Person person = Person.builder().name("Alice").age(30).build();

Without Lombok, achieving the same flexibility would require manually implementing a builder method or defining multiple constructors, leading to unnecessary code repetition.

The Challenge: Copying a Lombok Instance from a Superclass to a Subclass

In Java, a subclass automatically inherits properties and behavior from its superclass. Ideally, when creating a subclass instance from a superclass instance, all inherited fields should be copied without requiring manual effort.

Example: Using @Builder in an Inherited Class

@Builder
class Employee extends Person {
    private String department;
}

A problem arises when trying to convert an existing Person instance into an Employee.

Person person = Person.builder().name("Alice").age(30).build();
Employee employee = Employee.builder().department("Engineering").build();

Here, the Employee object does not inherit name and age automatically. This is because Lombok does not merge builders between superclasses and subclasses.

Does Lombok Natively Support Instance Copying Across Inheritance?

No, Lombok's @Builder does not automatically bridge superclass properties while instantiating a subclass. Each class requires its own builder, and there’s no built-in mechanism to copy data from an existing instance of a superclass to a subclass.

Why Doesn’t Lombok Handle Inheritance in @Builder?

Lombok generates builders separately for each annotated class. Since Java’s inheritance mechanism does not involve instance-copying by default, Lombok does not automatically populate subclass builders with parent properties.

Workarounds for Instance Copying in Lombok

Since Lombok does not support direct instance copying, developers must employ alternative approaches to transfer inherited properties effectively.

1. Manual Copying Approach

The most straightforward approach is to manually pass superclass properties while building a subclass instance:

Employee employee = Employee.builder()
    .name(person.getName())
    .age(person.getAge())
    .department("Engineering")
    .build();

This ensures all inherited properties are set, but it requires explicit input, reducing automation.

2. Custom Builder Methods

A dedicated builder method simplifies instance copying:

@Builder
class Employee extends Person {
    private String department;

    public static EmployeeBuilder fromPerson(Person person) {
        return Employee.builder()
            .name(person.getName())
            .age(person.getAge());
    }
}

Usage:

Employee employee = Employee.fromPerson(person).department("HR").build();

This method improves maintainability by reducing manual copying while retaining Lombok’s builder functionality.

3. Using Constructors for Copying

An alternative approach is to rely on constructors to transfer data:

public Employee(Person person, String department) {
    super(person.getName(), person.getAge());
    this.department = department;
}

Usage:

Employee employee = new Employee(person, "Sales");

This approach utilizes constructor chaining instead of a builder, making instance creation more structured.

4. Overriding Lombok’s Builder to Support Copying

Another advanced technique is extending Lombok’s builder pattern to include an inherited instance copying mechanism:

@Builder
class Employee extends Person {
    private String department;

    public static class EmployeeBuilder {
        public EmployeeBuilder fromPerson(Person person) {
            this.name = person.getName();
            this.age = person.getAge();
            return this;
        }
    }
}

Usage:

Employee employee = Employee.builder()
    .fromPerson(person)
    .department("Finance")
    .build();

This ensures a more flexible and reusable code structure.

Limitations of These Approaches

While these modifications address the limitations of inheritance within Lombok’s @Builder, they come with some drawbacks:

  • Manual Effort: Despite automation, developers still need to define explicit methods for copying.
  • Lombok’s Constraints: The default behavior of @Builder does not support deep inheritance structures.
  • Maintenance Overhead: Changes in the superclass require updates in all subclasses using these methods.

Best Practices for Handling Lombok’s @Builder with Inheritance

When leveraging Lombok while managing instance copying:

  1. Prefer Constructors—Using constructors helps avoid reliance on Lombok-specific solutions.
  2. Limit Builder Usage on Hierarchies—Since @Builder does not support inheritance seamlessly, avoid overusing it in deep class structures.
  3. Use Composition Over Inheritance—If instance conversion is frequent, consider aggregation instead of class extension to simplify object management.
  4. Leverage Static Utility Methods—Defining static transformation methods can provide scalable and reusable conversion logic.

External Libraries for Instance Copying

If extensive instance copying between class hierarchies is crucial, alternative libraries may provide better solutions:

  • MapStruct—Automatically maps fields between Java objects using annotations.
  • Dozer Mapper—A Java-based deep object mapping framework.
  • ModelMapper—Offers flexible object transformation with minimal setup.

These libraries streamline object conversion, eliminating the need for custom Lombok workarounds.

Final Thoughts

Lombok’s @Builder annotation simplifies object instantiation but does not inherently support copying instances from a superclass to a subclass. Developers must manually implement inheritance-aware logic using custom builder methods or constructors. For projects demanding frequent instance copying, alternative solutions like MapStruct may be a more sustainable choice. Ultimately, the best approach depends on project complexity and maintainability goals.

Citations

  • Bloch, J. (2008). Effective Java (2nd ed.). Addison-Wesley.
  • Gamma, E., Helm, R., Johnson, R., & Vlissides, J. (1994). Design Patterns: Elements of Reusable Object-Oriented Software. Addison-Wesley.
  • Oracle. (2023). The Java™ Language Specification. Retrieved from https://docs.oracle.com.
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading