关于java:在方法参数中使用NotNull Annotation

Using NotNull Annotation in method argument

我刚开始在Java 8中使用@NotNull注释并获得一些意想不到的结果。

我有这样的方法:

1
2
3
public List<Found> findStuff(@NotNull List<Searching> searchingList) {
    ... code here ...
}

我写了一个JUnit测试,传递参数searchList的null值。 我期待发生某种类型的错误,但它经历过,好像注释不在那里。 这是预期的行为吗? 根据我的理解,这是为了让您跳过编写样板空检查代码。

@NotNull应该做什么的解释将非常感激。


@Nullable@NotNull自行不做任何事情。它们应该充当文档工具。

@Nullable注释提醒您在以下情况下引入NPE检查的必要性:

  • 调用可以返回null的方法。
  • 取消引用可以为null的变量(字段,局部变量,参数)。
  • 实际上,@NotNull Annotation是一个明确的合同,声明如下:

  • 方法不应返回null。
  • 变量(如字段,局部变量和参数)不能保存空值。
  • 例如,而不是写:

    1
    2
    3
    4
    5
    6
    /**
     * @param aX should not be null
     */

    public void setX(final Object aX ) {
        // some code
    }

    您可以使用:

    1
    2
    3
    public void setX(@NotNull final Object aX ) {
        // some code
    }

    此外,@NotNull通常由ConstraintValidators检查(例如,在spring和hibernate中)。

    @NotNull注释不对其自身进行任何验证的原因是因为注释定义不提供任何ConstraintValidator类型引用。

    有关详情,请参阅:

  • Bean验证
  • NotNull.java
  • Constraint.java
  • ConstraintValidator.java

  • 如上所述@NotNull没有做任何事情。使用@NotNull的好方法是将它与Objects.requireNonNull一起使用

    1
    2
    3
    4
    5
    6
    7
    public class Foo {
        private final Bar bar;

        public Foo(@NotNull Bar bar) {
            this.bar = Objects.requireNonNull(bar,"bar must not be null");
        }
    }


    要使@NotNull处于活动状态,您需要Lombok:

    https://projectlombok.org/features/NonNull

    1
    import lombok.NonNull;

    关注:我应该使用哪个@NotNull Java注释?


    SO @NotNull只是一个标签...如果你想验证它,那么你必须使用像hibernate验证器jsr 303这样的东西

    1
    2
    3
    ValidatorFactory validatorFactory = Validation.buildDefaultValidatorFactory();
    Validator validator = validatorFactory.getValidator();
     Set<ConstraintViolation<List<Searching>> violations = validator.validate(searchingList);


    如果您使用的是Spring,则可以通过使用@Validated注释类来强制进行验证:

    1
    import org.springframework.validation.annotation.Validated;

    更多信息在这里:
    Javax验证@NotNull注释用法


    要在测试中测试方法验证,必须在@Before方法中包装代理。

    1
    2
    3
    4
    @Before
    public void setUp() {
        this.classAutowiredWithFindStuffMethod = MethodValidationProxyFactory.createProxy(this.classAutowiredWithFindStuffMethod);
    }

    然后,添加您的测试:

    1
    2
    3
    4
    5
    @Test
    public void findingNullStuff() {
     assertThatExceptionOfType(ConstraintViolationException.class).isThrownBy(() -> this.classAutowiredWithFindStuffMethod.findStuff(null));

    }