Lombok @Builder 模式下的 Collection 集合不可编辑的坑

323 阅读1分钟

1.现象

注意,如下面通过 @Builder 定义支持建造者模式的 Java Bean Model。

public class LombokBuilderListCase {

  @Data
  @AllArgsConstructor
  @NoArgsConstructor
  @Builder
  public static class Person {

    private String name;

    @Singular
    private List<String> rows;
  }


  @Data
  @AllArgsConstructor
  @NoArgsConstructor
  @Builder
  public static class Person2 {

    private String name;

    private List<String> rows = new ArrayList<>();
  }

  public static void main(String[] args) {
    case2();
    case3();
  }

  public static void case1() {

    Person person = Person.builder()
        .name("Maple")
        .row("At Jan.1")
        .row("At Feb.2")
        .build();

    //如果不给 row 赋值,加了 @Singular 后, rows 的结果是 Collections.emptyList(), 其也是一个不可进行修改的 list, 而不是我们原生定义的 list

    // Exception in thread "main" java.lang.UnsupportedOperationException
    person.getRows().add("March.3");

    // Exception in thread "main" java.lang.UnsupportedOperationException
    person.getRows().removeIf(item -> item.contains("2"));
  }


  public static void case2() {
    Person2 person = Person2.builder()
        .name("Maple")
        .build();
    //rows 是 null 空值
    List<String> rows = person.getRows();
    System.out.println(rows);
  }

  public static void case3() {
    Person2 person = new Person2();
    //row 是正常的 ArrayList
    List<String> rows = person.getRows();
    System.out.println(rows);
  }
}

2.总结

  • 如果在model里面初始化了 List 等集合类型,使用了 Builder 模式后,最终的对象都会忽略这些初始化的list 值信息。
  • Builder 模式下生成的 List 都是 unmodified 的,再在其基础上进行 add/removeIf 等操作都会进行报错, UnsupportedException.