Java 在方法参数中使用 NotNull Annotation

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/34094039/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 15:18:30  来源:igfitidea点击:

Using NotNull Annotation in method argument

java

提问by DavidR

I just started using the @NotNullannotation with Java 8 and getting some unexpected results.

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

I have a method like this:

我有一个这样的方法:

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

I wrote a JUnit test passing in the null value for the argument searchingList. I was expecting some type of error to happen but it went through as though the annotation was not there. Is this expected behavior? From what I understood, this was to allow you to skip writing the boilerplate null check code.

我编写了一个 JUnit 测试,传入参数 searchList 的空值。我原以为会发生某种类型的错误,但结果好像注释不存在一样。这是预期的行为吗?据我了解,这是为了让您跳过编写样板空检查代码。

An explanation of what exactly @NotNull is supposed to do would be greatly appreciated.

对@NotNull 究竟应该做什么的解释将不胜感激。

采纳答案by justAnotherUser...

@Nullableand @NotNulldo nothing on their own. They are supposed to act as Documentation tools.

@Nullable并且@NotNull什么都不做。它们应该充当文档工具。

The @NullableAnnotation reminds you about the necessity to introduce an NPE check when:

@Nullable注释会提醒您的必要性,介绍了NPE检查时:

  1. Calling methods that can return null.
  2. Dereferencing variables (fields, local variables, parameters) that can be null.
  1. 调用可以返回 null 的方法。
  2. 取消引用可以为空的变量(字段、局部变量、参数)。

The @NotNullAnnotation is, actually, an explicit contract declaring the following:

@NotNull注释是,实际上,在声明下面的一个明确的合同:

  1. A method should not return null.
  2. A variable (like fields, local variables, and parameters) cannot hold null value.
  1. 方法不应返回 null。
  2. 变量(如字段、局部变量和参数)不能保存空值。

For example, instead of writing:

例如,而不是写:

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

You can use:

您可以使用:

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

Additionally, @NotNullis often checked by ConstraintValidators(eg. in spring and hibernate).

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

The @NotNullannotation doesn't do any validation on its own because the annotation definitiondoes not provide any ConstraintValidatortype reference.

@NotNull注释不会做自己的任何验证,因为注释定义不提供任何ConstraintValidator类型的参考。

For more info see:

有关更多信息,请参阅:

  1. Bean validation
  2. NotNull.java
  3. Constraint.java
  4. ConstraintValidator.java
  1. Bean验证
  2. 非空文件
  3. 约束.java
  4. 约束验证器.java

回答by Naruto

SO @NotNull just is a tag...If you want to validate it, then you must use something like hibernate validator jsr 303

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

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

回答by gavenkoa

To make @NotNullactive you need Lombok:

@NotNull活跃起来,你需要 Lombok:

https://projectlombok.org/features/NonNull

https://projectlombok.org/features/NonNull

import lombok.NonNull;

Follow: Which @NotNull Java annotation should I use?

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

回答by Bollywood

As mentioned above @NotNulldoes nothing on its own. A good way of using @NotNullwould be using it with Objects.requireNonNull

如上所述@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");
    }
}

回答by sisanared

If you are using Spring, you can force validation by annotating the class with @Validated:

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

import org.springframework.validation.annotation.Validated;

More info available here: Javax validation @NotNull annotation usage

此处提供更多信息: Javax 验证 @NotNull 注释用法

回答by Julien Feniou

To test your method validation in a test, you have to wrap it a proxy in the @Before method.

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

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

With MethodValidationProxyFactory as :

使用 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());
}

}

}

And then, add your test :

然后,添加您的测试:

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

}

回答by WesternGun

I do this to create my own validation annotation and validator:

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

ValidCardType.java(annotation to put on methods/fields)

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 {};
}

And, the validator to trigger the check: CardTypeValidator.java:

并且,触发检查的验证器 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));
    }
}

You can do something very similar to check @NotNull.

您可以执行与 check 非常相似的操作@NotNull