我应该显式抛出NullPointerException还是让Java来为我做?
正如标题所说,我想知道关于抛出NullPointerException的最佳实践是什么。具体地说,如果我有一个外部库函数,它可以在我不想实际处理的情况下返回我应该显式抛出NullPointerException还是让Java来为我做?,java,null,nullpointerexception,Java,Null,Nullpointerexception,正如标题所说,我想知道关于抛出NullPointerException的最佳实践是什么。具体地说,如果我有一个外部库函数,它可以在我不想实际处理的情况下返回null(参见下面的特定示例),因为null表示软件有问题。问题是,我应该吗 检查null的返回值并自己抛出NullPointerException,或者 当我尝试使用对象时,我是否应该让Java为我做一些肮脏的工作 第一种方法允许我添加一些额外的信息,因为我可以构造NullPointerException,但在我看来,第二种方法有助于更干净
null
(参见下面的特定示例),因为null
表示软件有问题。问题是,我应该吗
null
的返回值并自己抛出NullPointerException,或者synthesizer = Central.createSynthesizer(generalDesc);
if (synthesizer == null) {
// (1) throw NPE explicitly
throw new NullPointerException("No general domain synthesizer found.");
}
// (2) let the JVM throw the NPE when dereferencing
synthesizer.allocate();
Central.createSynthesizer
如果找不到合适的合成器,则返回null
,这通常是由于缺少speech.properties文件造成的。因此,这是一个系统设置错误的问题,并且在运行时是不可恢复的,而不是需要以编程方式处理的情况。因此,我认为抛出NullPointerException是一个有效的响应,因为它表示一个bug(不是在代码中,而是在软件的部署中)。但是由于合成器
对象在下一条语句中被取消引用,我是否应该让JVM为我抛出NPE并保存空检查
附录:考虑到JVM启动时加载speech.properties需要存在于文件系统中(通常为“user.home”或“java.home/lib”),让人费解的是
createSynthesizer
没有直接抛出NPE(这是我最初在弗洛伊德纸条中写的)当它找不到它但返回null时。我认为在这里抛出NullPointerException是正确的做法,因为它表明软件部署中存在实际缺陷。我想说的是,您永远不应该显式创建NullPointerException
,而应该使用更清楚地描述情况的异常类型。在您的情况下,我认为IllegalStateException
适合“系统设置错误,在运行时无法恢复”的情况。或者您可以创建自己的组件missingexception
。在所需方法参数为null
的情况下,通常使用IllegalArgumentException
。在您的情况下:两者都不使用。检查null
并抛出更有意义的异常,而不是NPE
一般来说,如果NPE不应该出现,不要显式地测试它,Java会为您做的。编写的测试更少,读取的代码更少,分析的复杂性也更少
但是,如果预计null
,则应尽快测试并进行相应解释。否则,NullPointerException
将在稍后的某个地方以不同的行/方法出现,这使得调试真正的问题变得更加困难。我不喜欢让null成为有效的返回值,即使在“异常情况”下也是如此。因此,我采取了另一种方法
在你的例子中,我会用@NotNull(@NotNull是一个惊人的注释)注释方法createSynthesizer(…)。当createSynthesizer(…)想要返回null时,我会得到一个非法状态异常,而不是NPE
你会得到一个:
java.lang.IllegalStateException: @NotNull method .../.../createSynthetiser(...) must not return null
这种方法有几个好处:
- NullPointerException和IllegalStateException都扩展了RuntimeException,所以您不会从根本上更改程序
- 发生错误时,应立即抛出异常(而不是稍后,在您检查/抛出自己或尝试取消引用null时)
- 您无需费心编写if…==空/抛出部分
作为一个巨大的额外好处,一些IDE(如IntelliJ IDEA)将实时警告您可能发生的@NotNull违规行为。非常有趣的问题 我认为该方法应该抛出某种类型的
问题CreatingSynthesizerException
,而不是返回null
我会进行空检查,并抛出一个NPE或其他自定义
问题以及您自己的SynthesizeRexception
(出于某种原因,Sun将此异常视为JVM ish异常,不打算供程序员使用。这是一些认证教程和书籍中所说的。但是,我不相信这一点,有些人经常将自己的NPE放入我的库中)。关于原始代码:
synthesizer = Central.createSynthesizer(generalDesc);
if (synthesizer == null) {
// (1) throw NPE explicitly
throw new NullPointerException("No general domain synthesizer found.");
}
// (2) let the JVM throw the NPE when dereferencing
synthesizer.allocate();
我的看法是,如图所示抛出NPE是可以的,但是有很多警告。只有当NPE-ctor参数是一个足够描述性(并且希望是唯一的)消息(希望是从常量或资源集中提取的)时,才可以这样做另一个警告是,你的首要任务是把东西搬出去,在这种情况下,这算是一个可以接受的快速解决方案
在理想情况下,我的首选是使用特定于无效配置的异常。当这些异常不可用时,可以使用NPE子类(如Apache Commons Math)或者是在中发现的旧异常。这是我对NPE和IllegalArgument类型异常的立场。我不一定同意Apache Common Lang关于更喜欢使用标准JDK异常而不是语义相关的异常的观点。但这只是我,我正在脱离正切
…那么回到原来的问题。正如我之前所说的,像这样快速地抛出NPE是可以的(当你处于那种“需要把那个sh1t弄出来!!(10+1)”的情况下)
然而,请注意,这