2017-07-06 188 views
4

我有两个类Child延伸Parent。我需要在类上添加@Builder注释,以便我不需要创建自己的构建器。Lombok @builder上扩展了另一个类的类

package jerry;// Internal compiler error: java.lang.NullPointerException 

import lombok.AllArgsConstructor; 
import lombok.Builder; 

@AllArgsConstructor([email protected]__(@Builder)) 
public class Child extends Parent { 
//Multiple markers at this line 
// - Implicit super constructor Parent() is undefined. Must explicitly invoke another constructor 
// - overrides java.lang.Object.toString 

    private String a; 
    private int b; 
    private boolean c; 

} 


@Builder 
public class Parent { 
    private double d; 
    private float e; 
} 

我需要能够建立子实例,使得

Child child = Child.builder().a("aVal").b(1000).c(true).d(10.1).e(20.0F).build(); 

但到目前为止,我得到的侧提到,代码注释错误。任何人都可以指出我如何通过lombok或任何其他类似的库实现它的正确方向?

子问题

为什么@AllArgsConstructor([email protected]__(@Autowired))编译但@AllArgsConstructor([email protected]__(@Builder))不?

+0

我想目前评估https://github.com/rzwitserloot/lombok/pull/1337/commits。 – zur

回答

7

https://blog.codecentric.de/en/2016/05/reducing-boilerplate-code-project-lombok/@Builder和继承部分)

调整到你的类

@AllArgsConstructor 
public class Parent { 
    private double d; 
    private float e; 
} 

public class Child extends Parent { 
    private String a; 
    private int b; 
    private boolean c; 

    @Builder 
    public Child(String a, int b, boolean c, double d, float e) { 
    super(d, e); 
    this.a = a; 
    this.b = b; 
    this.c = c; 
    } 
} 

在此设置

Child child = Child.builder().a("aVal").b(1000).c(true).d(10.1).e(20.0F).build(); 

工作正常

+0

好点我尝试过......但是我不能提供超过7个参数给我的团队中的代码约定,如果我提供的参数超过7个参数,构建失败。我原来的代码在超级/父类中有超过30个字段 – zur

+1

我不知道是否可以在没有列出子构造函数/ @Builder中的所有父+子字段的情况下完成,至少我没有找到任何这样的例子。作为一种解决方法,你可能会考虑为这个特定的类压制这个代码约定(至少我认为它来自一些静态代码分析工具,如PMD,Findbugs,Sonar等可以被抑制) – hammerfest

0

我有一个相似但是用例略有不同。在我的情况下,我有一连串的抽象超类构建和执行请求。不同的请求共享一些通用参数,但并不是每个请求都支持所有参数。具体请求的构建者应仅提供设置给定请求的受支持参数的方法。

我开始使用基于构造器的构建器实现,但是这导致了过多的样板代码,尤其是如果您有多个要配置的字段时。我现在想出了以下解决方案,这对我来说看起来要干净得多。

基本上,具体的子类定义了Builder应该支持的实际字段,并且Getter注解导致相应的超类方法被覆盖。抽象超类中的getter甚至可以被定义为抽象,以要求具体实现来定义这些字段。

public abstract class AbstractSuperClass1 { 
    protected String getParamA() { return "defaultValueA"; } 

    public final void doSomething() { 
     System.out.println(getParamA()); 
     doSomeThingElse(); 
    } 

    protected abstract void doSomeThingElse(); 
} 

public abstract class AbstractSuperClass2 extends AbstractSuperClass1 { 
    protected String getParamB() { return "defaultValueB"; } 

    protected void doSomeThingElse() { 
     System.out.println(getParamB()); 
    } 
} 

import lombok.AccessLevel; 
import lombok.Builder; 
import lombok.Getter; 

@Getter(AccessLevel.PROTECTED) @Builder 
public class ConcreteClass1 extends AbstractSuperClass2 { 
    private final String paramA; 
    // Not supported by this implementation: private final String paramB; 

    public static void main(String[] args) { 
     ConcreteClass1.builder() 
      .paramA("NonDefaultValueA") 
      .build().doSomething(); 
    } 
} 

import lombok.AccessLevel; 
import lombok.Builder; 
import lombok.Getter; 

@Getter(AccessLevel.PROTECTED) @Builder 
public class ConcreteClass2 extends AbstractSuperClass2 { 
    private final String paramA; 
    private final String paramB; 

    public static void main(String[] args) { 
     ConcreteClass2.builder() 
      .paramA("NonDefaultValueA").paramB("NonDefaultValueB") 
      .build().doSomething(); 
    } 
}