0

This is probably a beginner question but I am getting confused.

I have 3 classes as shown below. How do I use lombok's @Builder annotation in this case.

I get an error in Class C when trying to do as below code.

Will Class C work if the parent class Class B also has @Builder annotation?

I get an error:- Error: java: builder() in ClassC cannot hide builder() in ClassB return type ClassCBuilder is not compatible with ClassBBuilder

Class C:

import lombok.Builder;
public class C extends B {
    private String fieldC;

    @Builder
    public C(String fieldC, String fieldB, String fieldA) {
        super(fieldB, String fieldA);
        this.fieldC = fieldC;
    }
}

Class B:

import lombok.Builder;
public class B extends A {
    private String fieldB;

    @Builder
    public B(String fieldB, String fieldA) {
        super(fieldA);
        this.fieldB = fieldB;
    }
}

Class A:

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
@AllArgsConstructor
public abstract class A {
    private String fieldA;
}
firstpostcommenter
  • 2,328
  • 4
  • 30
  • 59
  • I want to generate builders for the classes where Class C extends Class B and Class B extends an abstract Class A. So that When I use Class C then I should have access to all the fields in all 3 classes from the builder – firstpostcommenter May 07 '20 at 10:13
  • 2
    https://stackoverflow.com/questions/44948858/lombok-builder-on-a-class-that-extends-another-class – firstpostcommenter May 07 '20 at 10:15
  • https://stackoverflow.com/questions/6543328/private-members-in-java-inheritance/10355759 – firstpostcommenter May 07 '20 at 10:16
  • Class B able to access the private field "fieldA" using Class A's public constructor. Is it possible to make Class C also get access to "fieldA" without making the "fieldA" public? – firstpostcommenter May 07 '20 at 10:24
  • The given code is working fine. I don't know why I got the error initially. Probably a compilation issue – firstpostcommenter May 07 '20 at 12:49
  • https://stackoverflow.com/questions/35458367/why-a-final-class-cannot-be-inherited-but-a-final-method-can-be-inherited. Final class cannot be inherited so `@Value` cannot be used – firstpostcommenter May 08 '20 at 08:13
  • Will Class C work if the parent class Class B also has `@Builder` annotation? I get an error:- Error: java: builder() in ClassC cannot hide builder() in ClassB return type ClassCBuilder is not compatible with ClassBBuilder – firstpostcommenter May 08 '20 at 14:46
  • Is there a reason why you don't use `@SuperBuilder`, as suggested in my answer to the first question you linked to in your comment? – Jan Rieke May 08 '20 at 19:01
  • @JanRieke: SuperBuilder is still experimental so I dont think I can use it in my project – firstpostcommenter May 09 '20 at 07:40
  • 1
    Experimemtal in Lombok means more or less just: it's not the first priority for the Lombok team when it comes to bug fixes etc. It's unlikely that `@SuperBuilder` will be discontinued in the future, given the number of people that use it. A normal `@Builder` on classes with inheritance is typically not very handy, because it requires manual work (the constructors), and gives you duplicate `builder()` methods. – Jan Rieke May 09 '20 at 09:16

1 Answers1

1

@Builder should be added to the class not the constructor like so:

import lombok.Builder;
@Builder
public class C extends B {
    private String fieldC;

    public C(String fieldC, String fieldB, String fieldA) {
        super(fieldB, String fieldA);
        this.fieldC = fieldC;
    }
}

The @Builder annotation causes lombok to generate the inner Builder-class. Adding stuff like @Builder.Default to fields or methods will just modify the builder methods. See the following example from lombok's @Builder description page:

import lombok.Builder;
import lombok.Singular;
import java.util.Set;

@Builder
public class BuilderExample {
    @Builder.Default private long created = System.currentTimeMillis();
    private String name;
    private int age;
    @Singular private Set<String> occupations;
}

A class annotated with @Builder will automatically have an inner class named like the outer class but postfixed with 'Builder'. You can then instantiate such a builder by calling:

MyClass myObject = MyClass.builder().withSomething("abc").build();
TreffnonX
  • 2,924
  • 15
  • 23
  • in Class C constructor, I get an error that fieldA has private access – firstpostcommenter May 07 '20 at 10:10
  • Then you should make it `protected` instead of private. I think you cannot specify the setter as means to set the value, which is odd. – TreffnonX May 07 '20 at 10:15
  • Hi, will this work if child class is extending a parent class which also has @Builder annotation? I get an error:- Error: java: builder() in ClassC cannot hide builder() in ClassB return type ClassCBuilder is not compatible with ClassBBuilder – firstpostcommenter May 08 '20 at 14:45