简体   繁体   English

使用Lombok Builder注释抛出UnsupportedOperationException

[英]UnsupportedOperationException is thrown with Lombok Builder annotation

I am using Lombok for my project. 我正在使用Lombok进行我的项目。 My model looks like: 我的模型看起来像:

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

I want to do next operation: 我想做下一步操作:

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

Where instance is created: 在哪里创建实例:

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

Finally, I got: 最后,我得到了:

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

When I changed creating the instance without Lombok builder pattern everything is fine: 当我在没有Lombok构建器模式的情况下更改创建实例时,一切都很好:

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

I couldn't understand what is wrong with Lombok's builder pattern? 我无法理解Lombok的构建器模式有什么问题?

Due to GitHub issue 由于GitHub问题

Lombok @Builder is primarily meant for immutables (and uses either Collections.unmodifiableList or Guava's ImmutableList Lombok @Builder主要用于不可变的(并使用Collections.unmodifiableList或Guava的ImmutableList

that's why you have UnsupportedOperationException 这就是你有UnsupportedOperationException的原因

For greater certainty reproduce full code pattern where you have exception please. 为了更加确定,请复制完整的代码模式,请您有异常。

As said by @fbokovikov the @Builder annotation uses immutables so when you try to add an element in the list an exception is thrown. 正如@fbokovikov所说,@ @Builder注释使用不可变,因此当您尝试在列表中添加元素时,会抛出异常。

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

If you set a breakpoint to see the value returned by dto.getScreens() you can see its type is Collections$EmptyList . 如果设置断点以查看dto.getScreens()返回的值, dto.getScreens()可以看到其类型为Collections$EmptyList If you use the constructor of the DTO then the type is ArrayList and the exception is not thrown. 如果您使用DTO的构造函数,则类型为ArrayList并且不会抛出异常。

Try this: 尝试这个:

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

This way you are telling lombok to, on build, initialize screens with an empty ArrayList . 这样你就可以告诉lombok在构建时使用空ArrayList初始化screens

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM