使用Lombok Builder注释抛出UnsupportedOperationException

时间:2017-11-30 12:24:27

标签: java list runtimeexception lombok builder-pattern

我正在将Lombok用于我的项目。 我的模型看起来像:

@Builder
@Data @AllArgsConstructor
public class ScreenDefinitionDTO {
    @Singular
    private List<ScreenDeclaration> screens;
}

我想做下一步操作:

String screenName = ctx.screenName().getText();
ScreenDeclaration declaration = ParsingUtils
                .buildScreenDeclaration(StringUtils.trim(screenName));

创建实例的地方:

public static ScreenDefinitionDTO buildEmptyScreenDTO() {
    return ScreenDefinitionDTO.builder()
            .screens(new ArrayList<>())
            .build();
}

最后,我得到了:

Exception in thread "main" java.lang.UnsupportedOperationException
    at java.util.AbstractList.add(AbstractList.java:148)
    at java.util.AbstractList.add(AbstractList.java:108)

当我在没有Lombok构建器模式的情况下更改创建实例时,一切都很好:

public static ScreenDefinitionDTO buildEmptyScreenDTO() {
    return new ScreenDefinitionDTO(new ArrayList<>());
}

我无法理解Lombok的构建器模式有什么问题?

3 个答案:

答案 0 :(得分:6)

由于GitHub issue

  

Lombok @Builder主要用于不可变项(并使用其中之一)   Collections.unmodifiableList或Guava的ImmutableList

这就是你UnsupportedOperationException

的原因

为了更加确定,请复制完整的代码模式,请您有异常。

答案 1 :(得分:0)

正如@fbokovikov所说,@Builder注释使用不可变,因此当您尝试在列表中添加元素时,会抛出异常。

dto.getScreens().add(new ScreenDeclaration()) // throws java.lang.UnsupportedOperationException

如果设置断点以查看dto.getScreens()返回的值,则可以看到其类型为Collections$EmptyList。如果您使用DTO的构造函数,则类型为ArrayList,并且不会抛出异常。

答案 2 :(得分:0)

尝试一下:

@Builder
@Data @AllArgsConstructor
public class ScreenDefinitionDTO {
    @Singular.Default
    private List<ScreenDeclaration> screens = new ArrayList<>();
}

通过这种方式,您告诉Lombok在构建时使用空的screens初始化ArrayList