【问题标题】:Should I instantiate a field when I use lombok使用 lombok 时是否应该实例化一个字段
【发布时间】:2019-09-27 20:25:05
【问题描述】:

我使用 lombok 来省略 java bean 的 getter 和 setter。 这是《Spring in Action 5 edition》一书中的一个例子

一个java bean:

@Data
public class Taco {

  @Size(min=1, message="You must choose at least 1 ingredient")
  private List<String> ingredients;

}

控制器:

  @PostMapping
  public String processDesign(@Valid @ModelAttribute("design") Taco design, Errors errors, Model model) {
    if (errors.hasErrors()) {
      return "design";
    }
    System.out.println(design.getIngredients());    
    return "redirect:/orders/current";
  }

渲染视图:

<form method="POST">
        <input name="ingredients" type="checkbox" value="FLTO">
        <span>Flour Tortilla</span><br>

        <input name="ingredients" type="checkbox" value="GRBF">
        <span>Ground Beef</span><br>

</form>

当我提交表单并且没有选中复选框时,验证不起作用,在控制器中,errors.hasErrors() 为 false,design.getIngredients()null

那我改java bean中的代码:

  private List<String> ingredients=new ArrayList<>();

验证成功,用户将收到消息:“您必须选择至少一种成分”

但我的问题是:即使我已经使用了 lombok,我是否应该实例化一个字段,尤其是对于引用字段?有没有办法使用注释来做到这一点?

【问题讨论】:

  • 这是初始化一个字段,如果你想分配一个默认值(比如一个空的ArrayList),结合Lombok注解这样做是完全正常的。
  • 如果将@Size 替换为@NotEmpty 是否有效?
  • @JanRieke 在这种情况下有效,只有一个注释完全符合我的预期。但如果我希望用户至少选择两个项目,我必须同时使用 @NotEmpty@Size(min=2)

标签: java spring spring-mvc lombok


【解决方案1】:

您可以定义空构造函数并在其中初始化List。 Lomboks 构造函数将被覆盖。

@Data
public class Taco {

  @Size(min=1, message="You must choose at least 1 ingredient")
  private List<String> ingredients;

  public Taco() {
     ingredients = new ArrayList<>()
  }

}

【讨论】:

  • 可是我还是得手动做,lombok为什么不帮我自动做呢?
  • Lombok 仅添加构造函数和 getter/setter。这些很简单。初始化成员超出了它的范围。想想它是如何工作的。如果您需要LinkedList 而不是ArrayList,该怎么办?当您可以通过重写构造函数更简单地做到这一点时,使用注释来做到这一点太复杂了。
  • 但是为什么不使用问题中建议的字段初始化器呢?应该没有缺点,而且代码会更少。
  • 静态初始化器仅在类加载期间运行。将它用于可变类型可能容易出错。
  • 字段初始化器不是静态初始化器。
猜你喜欢
  • 2011-06-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-10-18
相关资源
最近更新 更多