在方法参数中使用NotNull Annotation

时间:2015-12-04 17:26:04

标签: java

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

我有这样的方法:

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

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

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

8 个答案:

答案 0 :(得分:106)

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

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

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

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

      /**
       * @param aX should not be null
       */
      public void setX(final Object aX ) {
          // some code
      }
      

      您可以使用:

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

答案 1 :(得分:14)

如上所述,@ NotNull本身不执行任何操作。使用@NotNull的一种好方法是将其与Objects.requireNonNull

一起使用
Car

答案 2 :(得分:5)

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

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

答案 3 :(得分:4)

要激活@NotNull,您需要Lombok:

https://projectlombok.org/features/NonNull

import lombok.NonNull;

关注:Which @NotNull Java annotation should I use?

答案 4 :(得分:1)

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

import org.springframework.validation.annotation.Validated;

更多可用信息: Javax validation @NotNull annotation usage

答案 5 :(得分:0)

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

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

然后添加您的测试:

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

}

答案 6 :(得分:0)

我这样做是为了创建自己的验证批注和验证器:

ValidCardType.java(用于方法/字段的注释)

@Constraint(validatedBy = {CardTypeValidator.class})
@Documented
@Target( { ElementType.ANNOTATION_TYPE, ElementType.METHOD, ElementType.FIELD })
@Retention(RetentionPolicy.RUNTIME)
public @interface ValidCardType {
    String message() default "Incorrect card type, should be among: \"MasterCard\" | \"Visa\"";
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};
}

然后,验证器触发检查: CardTypeValidator.java

public class CardTypeValidator implements ConstraintValidator<ValidCardType, String> {
    private static final String[] ALL_CARD_TYPES = {"MasterCard", "Visa"};

    @Override
    public void initialize(ValidCardType status) {
    }
    public boolean isValid(String value, ConstraintValidatorContext context) {
        return (Arrays.asList(ALL_CARD_TYPES).contains(value));
    }
}

您可以执行类似于检查@NotNull的操作。

答案 7 :(得分:-1)

I resolved it with

@JsonSetter(nulls = Nulls.AS_EMPTY)
@NotBlank
public String myString;

Request Json:
{
  myString=null
}
 Response:
 error must not be blank