当前位置: 首页 > 知识库问答 >
问题:

非空Lombok生成器属性的FindBugs检测器

伍弘盛
2023-03-14

我有很多使用Lombok生成器的@nonnull字段的类。

@Builder
class SomeObject {
    @NonNull String mandatoryField1;
    @NonNull String mandatoryField2;
    Integer optionalField;
    ...
}

但是,这为调用方提供了在不设置mandatoryfield的情况下创建对象的选项,如果使用该选项,将导致运行时失败。

SomeObject.builder()
          .mandatoryField1("...")
          // Not setting mandatoryField2
          .build();

我正在寻找在构建时捕捉这些错误的方法。

有一些非Lombok的方法,比如StepBuilder,甚至是构造函数来确保总是设置强制字段,但我对使用Lombok Builder实现这一点的方法感兴趣。

此外,我理解为了进行编译时检查而设计类(如step-builder或@allargsconstructor)会创建大量笨拙的代码--这就是为什么我要构建一个检测这些问题的编译后FindBugs步骤的原因。

现在,当我将@nonnull字段显式设置为null时,FindBugs确实会失败:

FindBugs检测到此故障,

new SomeObject().setMandatoryField1(null);

但它没有检测到这一点:

SomeObject.builder()
          .mandatoryField1(null)
          .build();
SomeObject.builder()
          .mandatoryField1("...")
          //.mandatoryField2("...") Not setting it at all.
          .build();
public static class SomeObjectBuilder {
    private String mandatoryField1;
    private String mandatoryField2;
    private Integer optionalField;

    SomeObjectBuilder() {}

    public SomeObjectBuilder mandatoryField1(final String mandatoryField1) {
        this.mandatoryField1 = mandatoryField1;
        return this;
    }

    // ... other chained setters.

    public SomeObject build() {
        return new SomeObject(mandatoryField1, mandatoryField2, optionalField);
    }
}
    null

我有以下几个问题:

  • 如果设置了@nonnull属性,是否有任何方法可以使用Lombok生成器导致生成时失败(在运行FindBugs时或其他情况下)?
  • 是否有任何自定义FindBugs检测器来检测这些故障?

共有1个答案

杜苏燕
2023-03-14

Lombok在生成@allargsconstructor时会考虑这些@nonnull注释。这也适用于由@builder生成的构造函数。这是示例中构造函数的解拼写代码:

SomeObject(@NonNull final String mandatoryField1, @NonNull final String mandatoryField2, final Integer optionalField) {
    if (mandatoryField1 == null) {
        throw new java.lang.NullPointerException("mandatoryField1 is marked @NonNull but is null");
    }
    if (mandatoryField2 == null) {
        throw new java.lang.NullPointerException("mandatoryField2 is marked @NonNull but is null");
    }
    this.mandatoryField1 = mandatoryField1;
    this.mandatoryField2 = mandatoryField2;
    this.html" target="_blank">optionalField = optionalField;
}

因此,FindBugs理论上可以发现问题,因为null检查存在于构造函数中,稍后在示例中使用null值调用该构造函数。然而,FindBugs可能还不够强大(到现在为止?),而且我不知道有任何定制检测器能够做到这一点。

问题仍然是,为什么lombok没有将这些检查添加到构建器的setter方法中(这将使FindBugs更容易发现问题)。这是因为使用仍然将@nonnull字段设置为null的构建器实例是完全合法的。请考虑以下用例:

TLDR:理论上可以找到这个问题,但是FindBugs还不够强大。另一方面,lombok不应该添加进一步的空检查,因为这会破坏合法的用例。

 类似资料:
  • 如何在下面的查询生成器代码段中获得industries page属性有值的结果?(即,其值不是空字符串)

  • MapStruct知道源状态检查,并且默认情况下使用状态检查器方法(如果存在的话)来验证目标对象中的字段是否应该使用源对象中的值更新。没有状态检查器,MapStruct默认只更新非空值的字段。 我想在REST控制器中使用DTO来使用MapStruct的source presence checknig实现部分更新策略,但是由于我使用Lombok来生成getter和setter,所以我还想生成sour

  • 我试图在使用openapi 3规范设计的API中引入可为null的属性。其思想是始终将属性返回给客户端,无论其值是否为null。 YAML文件(我先尝试了,没有默认,结果相同): 生成Java代码: API的响应: 因此,无论属性是否为null,结果总是“present:true”。如果没有nullability,它就可以正常工作,除了从响应中删除不需要的null值。 有什么想法吗? P、 该物业

  • 我正在尝试使用斯卡拉测试和斯卡拉检查设置基于属性的测试...根据预测,似乎我正在成功,但它需要太快了,从我通常的理解来看,ScalaCheck应该告诉你测试是如何运行的,在我的情况下,这些信息是不存在的: 下面是测试类: Gens 特征是我的 - 它只包含Gen[数组[Int]的定义: 我使用这个源进行测试设置。以防万一,我提供了scalacheck和scalatest的版本(来自Dependen

  • 我试图将Lombok与JavaFX属性结合使用: 这将为属性本身生成getter和setter: null getID():int 集合id(int id) GetIdProperty():SimpleIntegerProperty getName():string setName(字符串名称) GetNameProperty():SimpleStringProperty ... 这在龙目岛支持吗

  • 解决方案: 我不得不更改我的和的顺序。 我必须将放在之上,然后它就起作用了。 我将下面的pom更新到工作版本,所以这里没有非工作代码。 我还将lombok版本转换回当前版本,而不是使用edge版本。 原始问题: 我有2个或多或少相同的类集(见下面的示例) 一组是我的API的DTO,我希望它是不可变的,使用Lombok的@Value和@Builder 一组是要存储在数据库中的实体。使用Lombok的