为什么NullPointerException没有被声明为已检查异常?

25
这是一道面试题:“NullPointerException”很普遍,为什么它没有被声明为已检查的异常?我在谷歌上搜过,但没有找到合适的答案。
9个回答

38

几乎每个方法都必须声明抛出它。

public void myMethod(String param) throws NullPointerException {
   //
}

(顺带一提,例如Eclipse会在存在“可能的空指针访问”时发出警告,以便您尽早预防异常。)


9
另外,专门捕获空指针异常几乎总是一个坏主意。 - Joachim Sauer
如果Java有可能声明一个函数不会抛出某个异常,那么就可以将throws NullPointerException作为每个函数的默认值。然后可以声明不会抛出NullPointerException的函数,例如public void myMethod(String param) does not throw NullPointerException或使用!throws - asmaier

16

这不是一个检查异常(等等原因),因为它非常普遍。它几乎可以在任何地方发生。如果它是被检查出来的,那么几乎每个 Java 程序中的每个方法都必须声明它会抛出 NullPointerException


12

空指针异常是运行时异常的扩展,因此它们是程序流程中意外发生的。期望抛出空指针异常是没有意义的(希望如此!),因此您永远不会将其声明为受检异常。


6

检查异常可能会发生,因为程序无法控制的环境出了问题(例如IOExceptionSQLException)。你可以预见到并处理这种情况。

NullPointerException通常发生是因为代码中存在一些错误。如果你期望抛出NullPointerException,则正确的解决方案是修复错误而不是处理异常。


@Heinzi - 我不同意“发生在环境中的某些事情”的观点。例如,当凭据不正确时,JAAS登录模块可能会抛出LoginException。或者,在某些业务场景下,AccountService可能会抛出InsufficientBalanceException。因此,它们本质上并非与“环境”相关。 - ring bearer
2
嗯,人们可以将用户输入和数据存储视为“环境”的一部分,因为它们是与代码本身的逻辑外部相关的。 - Dave Costa
@ring bearer,LoginException 在大多数情况下是一个配置(环境)问题(用户未被配置或未使用该密码进行配置)。检查异常可以按您所描述的方式用于 AccountService,但由于它是理论上自行开发的 API 的一部分,我不认为它是一个好的例子。 - Yishai
2
@Yishai 让我用两句话总结一下。已检查 - 客户端(调用者)必须采取恢复操作(环境或其他方面) 未检查 - 编程错误 - ring bearer

4

我给出的简短回答是,这是程序错误的结果,而程序错误异常不是被检查的异常(IllegalStateException、ClassCastException等)。

但即使你有理由认为它应该是一个被检查的异常,基本上每个操作对象引用的操作都可能抛出它,所以它会无处不在,非常麻烦,而且每个非平凡程序中的方法都必须抛出它——那还有什么意义呢?


3

我对检查异常的定义是,当API出现已知的不良情况时会引发检查异常。

NullPointerException并不表示"已知的不良"情况。相反,它们通常是由于代码中存在某些未处理的情况而抛出的。也就是说,它们大部分时间都是由于糟糕的编码实践导致的——例如尝试获取未正确初始化的列表的大小等。因此,没有必要将它们作为检查异常——因为Java中的每个对象在某个时刻都可能为空?!NullPointerException也永远不应该被捕获。


2
这听起来像是迪克·切尼所说的“已知未知”和“未知未知”。;-) - Stephen C
@yaneeve,我认为你所说的“caught”是指像if(myList != null)这样的检查语句。除此之外,在代码中不应该有类似于catch(NullPointerException npe)的内容。那样的话,它应该永远不会通过代码审查。 - ring bearer
2
NPE是程序员错误的结果。即使是完美的编码人员也无法控制是否会出现IOException。这就是区别所在。 - DJClayworth
1
@Yishai - IOException是一个“已知的不良反应”,因为例如当我调用createNewFile()时,可能会发生已知的不良反应,如磁盘空间不足。 - ring bearer
@StephenC 这实际上是拉姆斯菲尔德的名言。 - sjr
显示剩余4条评论

1

已检查异常仅适用于程序可以恢复的异常。在 NULL 对象上调用某些内容是程序员的问题,无法恢复。


0

为什么要包含它,当你编写的每个函数都必须声明它?只是为了让你的生活更简单。


0

如果发生空指针异常,您的程序将会停止运行。因此,它是未被检查的异常。


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