17

我有一个类产品:

   @Data
   @SuperBuilder
   public class Product {

        private String name;
        private String manufacturer;

   }

和一个扩展类

@Data
@SuperBuilder
public class Frame extends Product{

   private String model;

}

我正在尝试使用构建器创建一个 Frame 对象:

 return Frame.builder() 
        .name("Frame ABC")
        .manufacturer("Manufacturer")
        .model("Model 1")
        .build();

我正在使用带有 Lombok 插件的 IntelliJ 2019.1.1,但不幸的是,编译器将.name().manufacturer()方法标记为错误。我看到这个问题打开了,我想知道是否有一种解决方法可以让我的代码正常工作。

4

3 回答 3

6

不,直到问题得到解决。

这是鸡和蛋的问题。在编译带有 @SuperBuilder 注释的类之前,实际生成的构建器方法不存在。该插件(一旦更新/修复)适用于这些方法的 IDE,因此即使它们尚不存在,该插件也会告诉 IDE 在编译发生时它们将是什么。

有很多方法可以“作弊”,但它们都是 hack - 例如,您可以在自己的 jar 中编译您的(超级)构建器类,然后将该 jar 导入您的项目中。当您编译 SuperBuilder 类时,它们现在包含所有生成的方法,因此 IDE 将看到实际的方法,因此如果您尝试使用它们,它将提出它们。功能性但不是很有用...如果您需要更新 SuperBuilder 注释类,您现在必须每次在更改变得可见之前编译它们。显然,您可以创建构建任务来为您执行此操作,但您总是在解决插件支持的实际问题。

于 2019-05-05T19:20:57.650 回答
3

此解决方法对我有用:

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Product {

  private String name;
  private String manufacturer;

}

@Data
@NoArgsConstructor
public class Frame extends Product{

   private String model;

   @Builder
   public Frame(String name, String manufacturer, String model){
      super(name, manufacturer);
      this.model = model;
   }

}

我看到的唯一问题是当你在类中有很多字段时,编写这样的构造函数会变得很烦人,但我仍然认为这是值得的,因为最后你可以访问父字段和子字段。

 return Frame.builder()
        
        .name("Frame ABC")
        
        .manufacturer("Manufacturer")
        
        .model("Model 1")
        
        .build();
于 2019-07-30T13:34:50.740 回答
2

首先使用子成员字段构建,然后是父成员字段,类型转换似乎对我有用:

return (Frame) Frame.builder()
                    .model("Model 1")
                    .name("Frame ABC")  
                    .manufacturer("Manufacturer")    
                    .build();
于 2019-11-28T04:58:40.093 回答