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应该做什么的解释将非常感激。
-
@NotNull只是一个注释。注释本身不做任何事情。它们在编译时需要注释处理器,或者在运行时处理它的东西。
-
您是否在应用程序服务器中运行代码(例如使用Arquillian)?
-
@SotiriosDelimanolis - 那么重点是什么,只是警告任何调用该方法的人不要传递空值?在这种情况下,您仍然需要空指针验证代码。
-
看看hibernate验证器
-
@ jabu.10245 - 不使用任何应用程序服务器。
-
@arisalexis - 我在我的类路径中有org.hibernate:hibernate-validator:5.2.2.Final。
-
那就是答案。请参阅本教程。您需要某种JavaEE容器(例如CDI)才能工作。或者可能是Hibernate验证,就像评论建议的那样。虽然没有尝试过。
-
仅包括它是不够的!"某人"需要激活它
-
@arisalexis - 我正在使用Spring并且在我的Application类中有一个LocalValidatorFactoryBean,我认为应该公开它以供使用?
@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部分的第2部分,它真的应该说"不应该",而不是"不能"因为它不能强制执行吗?或者如果它可以在运行时强制执行,你会怎么做呢?
-
是的,它是"不应该"......方法实施应该强制执行合同。
-
或者,在Java 8中,可以在返回值中使用Optional代替@Null,并在参数列表中使用方法重载代替@Null:dolszewski.com/java/java-8-optional-use-cases
-
我相信混淆来自NotNull注释的java文档:* The annotated element must not be {@code null}. * Accepts any type.我认为必须将word替换为should但是它又取决于你如何阅读它。肯定会有一些更好的澄清
如上所述@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");
}
} |
-
只是一个提示。您也可以使用一行编写此类作业:this.bar = Objects.requireNonNull(bar,"bar must not be null");
-
感谢您的提示@lolung - 我现在根据您的评论更新了上面的代码。
要使@NotNull处于活动状态,您需要Lombok:
https://projectlombok.org/features/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); |
-
在方法的开头我在哪里放这个?
-
是..在方法的开头......这只是验证实现之一,可能还有其他的......
-
好。但是这个代码所做的重要性不会改变我是否在param参数中有@NotNull注释?
-
现在你在集合中拥有所有违规,检查它的大小,如果它大于零,则从方法返回。
如果您使用的是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));
} |