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

我有一个这样的方法:

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

我写了一个JUnit测试,传入参数searchingList的空值。我期望发生某种类型的错误,但它通过,就好像注释不存在一样。这是预期的行为吗?根据我的理解,这是为了允许您跳过编写样板空检查代码。

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


当前回答

I resolved it with

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

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

其他回答

I resolved it with

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

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

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

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

使用MethodValidationProxyFactory作为:

import org.springframework.context.support.StaticApplicationContext;
import org.springframework.validation.beanvalidation.MethodValidationPostProcessor;

public class MethodValidationProxyFactory {

private static final StaticApplicationContext ctx = new StaticApplicationContext();

static {
    MethodValidationPostProcessor processor = new MethodValidationPostProcessor();
    processor.afterPropertiesSet(); // init advisor
    ctx.getBeanFactory()
            .addBeanPostProcessor(processor);
}

@SuppressWarnings("unchecked")
public static <T> T createProxy(T instance) {

    return (T) ctx.getAutowireCapableBeanFactory()
            .applyBeanPostProcessorsAfterInitialization(instance, instance.getClass()
                    .getName());
}

}

然后,添加你的测试:

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

}

如上所述,@ notull本身不做任何事情。使用@ notull的一个好方法是将它与Objects.requireNonNull一起使用

public class Foo {
    private final Bar bar;

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

所以@NotNull只是一个标签…如果您想验证它,那么必须使用hibernate验证器jsr 303之类的东西

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

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

@Nullable Annotation提醒你在以下情况下引入NPE检查的必要性:

调用可以返回null的方法。 取消可以为空的变量(字段、局部变量、参数)的引用。

@NotNull注释实际上是一个明确的契约,声明如下:

方法不应该返回null。 变量(如字段、局部变量和参数)不能保持空值。

例如,不要写:

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

你可以使用:

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

此外,@NotNull通常由ConstraintValidators检查。在春天和冬眠)。

@ nottnull注释本身不做任何验证,因为注释定义没有提供任何ConstraintValidator类型引用。

更多信息见:

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