我应该显式抛出一个NullPointerException还是让Java为我做这件事?

2022-09-04 19:42:05

正如标题所说,我想知道抛出NullPointerExceptions的最佳实践是什么。具体来说,如果我有一个外部库函数,它可以在我不想实际处理的情况下返回(请参阅下面的特定示例),因为这表明软件存在问题。问题是,我应该nullnull

  1. 检查的返回值并自己抛出 NullPointerException,或者null
  2. 我应该让Java在我试图使用对象时立即为我做肮脏的工作。

第一种方法允许我添加一些额外的信息,因为我可以构造NullPointerException,但在我看来,第二种方法使代码更清晰。我还想知道任何性能影响,也就是说,Java在“本机”抛出NPE方面是否更有效?

例如,我正在尝试使用以下代码使用 Java 语音 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如果找不到合适的合成器,则返回,这通常是由缺少 speech.properties 文件引起的。因此,这是一个系统设置错误的问题,并且从运行时就无法恢复,而不是需要以编程方式处理的情况。因此,我相信抛出NullPointerException是一个有效的响应,因为它表示一个错误(不是在代码中,而是在软件的部署中)。但是,由于对象在下一个语句中被取消引用,我是否应该让JVM为我抛出NPE并保存空检查?nullsynthesizer

补遗:考虑到当JVM启动时,speech.properties被加载,需要存在于文件系统上(通常)“user.home”或“java.home/lib”中,令人费解的是,当它无法找到它但返回null时,它不会直接抛出NPE(这是我最初在弗洛伊德的滑移中写的)。我认为抛出一个NullPointerException在这里是正确的做法,因为它表明了软件部署中的实际错误。createSynthesizer


答案 1

在你的情况下:两者都不是。检查并引发更有意义的异常,而不是 NPE。null

一般来说 , 如果 NPE 不应该发生,不要显式测试它,Java 会为你做。编写测试更少,读取代码更少,分析复杂性更低。

但是,如果预期,请尽快对其进行测试并相应地进行解释。否则,稍后将在不同的行/方法的某个位置发生,使得调试实际问题变得更加困难。nullNullPointerException


答案 2

我想说的是,你永远不应该显式创建一个,而是使用一个更清楚地描述情况的异常类型。在你的情况下,我会说会适合“系统设置错误,并且从运行时恢复”的情况。或者你可以创建自己的.在必需的方法参数为 的情况下,通常使用 。NullPointerExceptionIllegalStateExceptionComponentMissingExceptionnullIllegalArgumentException