java 在方法参数中使用NotNull注解

zmeyuzjn  于 2023-06-28  发布在  Java
关注(0)|答案(8)|浏览(295)

我刚开始在Java 8中使用@NotNull注解,并得到了一些意想不到的结果。
我有一个这样的方法:

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

我编写了一个JUnit测试,为参数searchingList传入null值。我预计会发生某种类型的错误,但它通过了,好像注解不在那里。这是预期的行为吗?据我所知,这是为了让您跳过编写样板空检查代码。
如果能解释一下@NotNull到底应该做什么,我们将不胜感激。

fykwrbwg

fykwrbwg1#

@Nullable@NotNull本身不执行任何操作。它们应该充当文档工具。

@Nullable注解提醒您在以下情况下引入NPE检查的必要性:
1.调用可以返回null的方法。
1.取消引用可以为null的变量(字段、局部变量、参数)。
@NotNull Annotation实际上是一个显式合约,声明如下:
1.方法不应返回null。
1.变量(如字段、局部变量和参数)不能should not保存空值。
例如,不要写:

/**
 * @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检查(例如,Spring和Hibernate)。
@NotNull注解本身不做任何验证,因为annotation definition不提供任何ConstraintValidator类型引用。

更多信息请参见:

  1. Bean validation
    1.注解类型NotNull
    1.注解类型Constraint
    1.接口ConstraintValidator
h43kikqp

h43kikqp2#

如上所述,@NotNull本身什么也不做。使用@NotNull的一个好方法是将其与Objects.requireNonNull一起使用

public class Foo {
    private final Bar bar;

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

qacovj5a4#

如果你使用Spring,你可以通过用@Validated注解类来强制验证:

import org.springframework.validation.annotation.Validated;

更多信息可在这里:Javax @NotNull annotation usage
您也可以使用**@NonNull**from projectlombok(lombok.NonNull)

kqqjbcuj

kqqjbcuj5#

所以@NotNull只是一个标记……如果你想验证它,那么你必须使用类似hibernate validator jsr 303的东西

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

wljmcqd86#

我这样做是为了创建自己的验证注解和验证器:
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非常类似的操作。

kognpnkq

kognpnkq7#

要在测试中测试方法验证,必须将其 Package 为@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));

}
zz2j4svz

zz2j4svz8#

I resolved it with

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

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

相关问题