为什么@Nonnull注释需要在运行时进行检查?

59

我有一个带有以下签名的函数

public static String myFunction(@Nonnull String param)
当我将参数设置为空时,我会收到以下异常:
Caused by: java.lang.IllegalArgumentException: Argument for @Nonnull parameter 'param' of com/MyClass.myFunction must not be null
    at com.MyClass.$$$reportNull$$$0(MyClass.java) 

javax.annotation.Nonnull在运行时不应该被检查。

到底是谁抛出了异常以及为什么会抛出异常呢?

P.S. 我使用Oracle JDK 1.8.0_102,从IntelliJ IDEA 2016.3以调试模式运行Tomcat服务器。


实际上,@Jesper,这些新的注释是为了在编译时检查事物而添加的。您可以查看我的答案。"当您在命令行中包含NonNull模块编译代码时,如果检测到潜在问题,编译器会打印警告信息"。 - Bruno
2
@BrunoDM - 这是运行时异常。 - Dmitry
1个回答

87

当你在IntelliJ IDEA中编译项目时,它会操纵已编译类的字节码以添加对各种类型@Nonnull注释的运行时检查。此行为由以下选项控制:

设置 | 构建、执行、部署 | 编译器 | [x] 为非空注解方法和参数添加运行时断言。

“为非空注解方法和参数添加运行时断言”屏幕截图


4
这个功能在 IntelliJ IDEA 5.0 版本中就已经加入,但当时它只支持 JetBrains 的 @NotNull 注解。最近才添加了对其他注解的支持。 - yole
48
因此,它精彩地编译了与构建工具链不同的代码。这在许多方面都是错误的。例如,当从IntelliJ运行单元测试时,可能会导致测试失败,但如果通过maven运行,则会通过。也许用户进行了空值检查和特定异常抛出,并且单元测试验证该异常和消息,但这会成为障碍。 - Scott Carey
9
我认为这是一个错误。注释并不意味着运行时检查,任何添加了运行时检查的构建都会违反注释合同,即没有运行时检查。他们当时在想些什么?更糟糕的是,他们将其设置为默认打开而非手动选择。 - tkruse
12
如果你不喜欢这个功能,可以将其禁用。在Java中处理空值是我经历过的最大痛点之一。感谢IntelliJ在这方面提供了帮助。 - linqu
5
在Maven中(不使用Lombok),是否可能获得这些运行时检查? - Jatin
显示剩余6条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接