我应该显式抛出一个NullPointerException,还是让Java为我做?
正如标题所说,我想知道关于抛出NullPointerExceptions的最佳做法。 具体来说,如果我有一个外部库函数可以在我不想实际处理的情况下返回null
(参见下面的具体示例),因为null
表示软件有问题。 问题是,我应该
null
的返回值并自己抛出NullPointerException,或者 第一种方法让我添加一些额外的信息,因为我得到构建NullPointerException,但第二种方法使我认为更干净的代码。 我还想知道任何性能影响,也就是说,Java在“NPE”本身是否更有效?
举例来说,我试图使用Java Speech API来创建一个语音合成器,使用下面的代码:
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是一个有效的响应,因为它表示一个错误(不是在代码中,而是在软件的部署中)。 但是由于synthesizer
对象在下一个声明中被解除引用,我应该让JVM为我提供NPE并保存空值检查吗?
附录:考虑到当JVM启动时需要在(通常)“user.home”或“java.home / lib”文件系统中存在的话,speech.properties会被加载,但令人费解的是, createSynthesizer
不能直接抛出NPE (这是我最初写在一个弗洛伊德滑),当它无法找到它,但返回null。 我认为抛出一个NullPointerException在这里是正确的,因为它表示软件部署中的一个实际错误。
在你的情况:既不。 检查null
并抛出更有意义的异常,而不是NPE。
一般来说 - 如果NPE不应该发生,不要明确地测试它,Java会为你做。 少写测试,少阅读代码,分析复杂度低。
但是,如果预计为null
则尽快进行测试并据此进行解释。 否则, NullPointerException
将在稍后以不同的行/方法出现,使调试真正的问题变得更加困难。
我会说你永远不应该明确地创建一个NullPointerException
,而应该使用一个更清楚地描述情况的异常类型。 在你的情况下,我会说IllegalStateException
将适合“系统的错误设置,并且在运行时非常不可恢复”的情况。 或者你可以创建你自己的ComponentMissingException
。 在所需的方法参数为null
情况下,通常使用IllegalArgumentException
。
即使在“特殊情况下”,我也不想让null成为有效的返回值。 所以我采取另一种方法。
在你的情况下,我会使用@NotNull注释方法createSynthesizer(...)(@NotNull是一个了不起的注释)。 一旦createSynthesizer(...)想要返回null,我将取得一个IllegalStateException而不是NPE。
你会得到一个:
java.lang.IllegalStateException: @NotNull method .../.../createSynthetiser(...) must not return null
这种方法有几个好处:
NullPointerException和IllegalStateException都会扩展RuntimeException,因此您不会从根本上更改程序
当错误发生(不晚于,一旦你要么检查/你扔或一旦你尝试取消引用空)异常应立即抛出
你不必费心编写if ... == null / throw部分了。
作为一个巨大的附加优势,某些IDE(如IntelliJ IDEA)会实时警告您可能存在@NotNull违规行为。
链接地址: http://www.djcxy.com/p/76213.html上一篇: Should I throw a NullPointerException explicitly or let Java do it for me?