Java 在方法参数中使用NotNull注释
我刚开始在Java8中使用Java 在方法参数中使用NotNull注释,java,Java,我刚开始在Java8中使用@NotNull注释,得到了一些意想不到的结果 我有这样一种方法: public List<Found> findStuff(@NotNull List<Searching> searchingList) { ... code here ... } public List findStuff(@NotNull List searchingList){ …代码在这里。。。 } 我编写了一个JUnit测试,为参数searchingList
@NotNull
注释,得到了一些意想不到的结果
我有这样一种方法:
public List<Found> findStuff(@NotNull List<Searching> searchingList) {
... code here ...
}
public List findStuff(@NotNull List searchingList){
…代码在这里。。。
}
我编写了一个JUnit测试,为参数searchingList传递空值。我原以为会发生某种类型的错误,但结果却好像没有注释一样。这是预期的行为吗?据我所知,这是为了允许您跳过编写样板文件的空检查代码
如果您能解释一下@NotNull应该做什么,我们将不胜感激。
@Nullable
和@NotNull
自己什么也不做。它们应该充当文档工具。
@Nullable
注释提醒您在以下情况下引入NPE检查的必要性:
@NotNull
注释实际上是一个明确的契约,声明了以下内容:
/**
* @param aX should not be null
*/
public void setX(final Object aX ) {
// some code
}
您可以使用:
public void setX(@NotNull final Object aX ) {
// some code
}
此外,@NotNull
通常由(例如,在春季和冬眠期)进行检查
@NotNull
注释本身不进行任何验证,因为不提供任何约束验证器
类型引用
有关更多信息,请参阅:
所以@NotNull只是一个标记……如果您想验证它,那么必须使用类似hibernate验证器JSR303的东西
ValidatorFactory validatorFactory = Validation.buildDefaultValidatorFactory();
Validator validator = validatorFactory.getValidator();
Set<ConstraintViolation<List<Searching>> violations = validator.validate(searchingList);
ValidatorFactory=Validation.buildDefaultValidatorFactory();
Validator Validator=validatorFactory.getValidator();
设置以激活@NotNull
您需要Lombok:
如下:如上所述,@NotNull
本身不做任何事情。使用@NotNull
的一个好方法是将其与
如果您使用的是Spring,则可以通过使用@Validated
注释类来强制验证:
import org.springframework.validation.annotation.Validated;
更多信息请访问:
要在测试中测试方法验证,必须在@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());
}
我这样做是为了创建自己的验证注释和验证程序:
ValidCardType.java
(在方法/字段上添加注释)
@约束(validatedBy={CardTypeValidator.class})
@记录
@目标({ElementType.ANNOTATION\u TYPE,ElementType.METHOD,ElementType.FIELD})
@保留(RetentionPolicy.RUNTIME)
public@interface ValidCardType{
String message()default“不正确的卡类型,应在下列各项中:\“MasterCard\”\“Visa\”;
类[]组()默认值{};
类@NotNull
只是一个注释。注释本身不起任何作用。它们在编译时需要一个注释处理器,或者在运行时需要处理它的东西。您是否在应用程序服务器中运行代码(例如使用)?@SotiriosDelimanolis-那么重点是什么,只是警告调用该方法的任何人不要传递空值?在这种情况下,您仍然需要空指针验证代码。请看hibernatevalidator@jabu.10245-不使用任何应用程序服务器。我应该将其放在何处,在方法的开头?是..在方法的开头…this只是其中一个验证实现,可能还有其他验证实现…好的。但无论我在param参数中是否有@NotNull注释,该代码的意义都不会改变。现在,您已经拥有了集合中的所有违规行为,请检查其大小,如果其大于零,则从方法返回。因此,请澄清本文的第2部分NotNull部分,真的应该说“不应该”,而不是“不能”,因为它不能强制执行?或者如果它可以在运行时强制执行,你会怎么做?是的,它是一个“不应该”…方法实现应该强制执行契约。或者,在Java 8中,可选的
可以用来代替返回值中的@Null
,方法重载可以代替参数列表中的@Null
:我相信混淆来自NotNull注释的Java文档:*注释元素不能为{@code null}*可接受任何类型。
我认为必须用should替换单词,但这取决于您的阅读方式。肯定需要更多的澄清have@Julian我认为must是正确的术语,因为它是一个规则,而不是一个建议。如果您使用的注释不应传递null
,但它将是允许,您使用的批注是错误的。该术语并不意味着它已验证。但是,未验证的提示不会有任何影响。如果要添加自动验证,可以使用一些外部工具。例如,IntelliJ IDE具有内置的注入空检查的支持。只需提示。您也可以使用on编写此类分配e行:this.bar=Objects.requirennull(条,“条不能为空”)
感谢@lolung的提示-我现在已经根据您的评论更新了上面截取的代码。如果条形字段使用NotNull,那么对Objects.requirennull的调用仍然会生成警告,因为requirennull方法不会返回NotNull引用。您能否提供更多解释,说明这将如何帮助解决as问题科克的问题?
@Before
public void setUp() {
this.classAutowiredWithFindStuffMethod = MethodValidationProxyFactory.createProxy(this.classAutowiredWithFindStuffMethod);
}
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));
}
I resolved it with
@JsonSetter(nulls = Nulls.AS_EMPTY)
@NotBlank
public String myString;
Request Json:
{
myString=null
}
Response:
error must not be blank