空参数应该抛出IllegalArgumentException还是NullPointerException?

574

我有一个简单的属性设置方法,对于这个特定的属性,null 是不合适的。在这种情况下,我一直很犹豫:是抛出 IllegalArgumentException,还是抛出 NullPointerException?从 javadocs 中来看,两者似乎都可以。是否有某种明确的标准?或者这只是其中一种情况,你应该按照自己的喜好去做,而且两种做法都是正确的呢?

26个回答

-1

理想情况下,应该避免抛出运行时异常。针对您的情况应创建一个已检查的异常(业务异常)。因为如果抛出并记录了其中任何一种异常,会在开发人员阅读日志时给他们带来误导。相反,业务异常不会引起恐慌,通常在故障排除日志中被忽略。


-1
在这种情况下,IllegalArgumentException 通过使用您的 API 向用户传达“不应为空”的明确信息。正如其他论坛用户指出的那样,只要您使用 API 向用户传达正确的信息,您可以使用 NPE。GaryF 和 tweakt 引用了《Effective Java》(我发誓)推荐使用 NPE。查看其他良好 API 的构建方式是构建您的 API 的最佳方法。
另一个很好的例子是查看 Spring APIs。例如,org.springframework.beans.BeanUtils.instantiateClass(Constructor ctor, Object[] args) 有一行 Assert.notNull(ctor, "Constructor must not be null")。org.springframework.util.Assert.notNull(Object object, String message) 方法检查传入的参数(对象)是否为 null,如果是,则抛出新的 IllegalArgumentException(message),然后在 org.springframework.beans.BeanUtils.instantiateClass(...) 方法中捕获。

-1

上面两个异常链接中的定义如下:

IllegalArgumentException:表示方法已传递了非法或不适当的参数。

NullPointerException:在应用程序试图在需要对象的情况下使用null时抛出。

这里的重大区别是,IllegalArgumentException 应该在检查方法参数是否有效时使用。而 NullPointerException 应该在对象为 null 时被“使用”时使用。

希望这有助于更好地理解这两个异常。


1
重点是使用null的是应用程序,而不是运行时。因此,“当方法传递了非法或不适当的参数”和“当应用程序使用null”之间存在相当大的重叠。理论上,如果一个应用程序为需要非空字段传递了null,则两个标准都得到满足。 - Christopher Smith

-1

如果是“setter”,或者我在获取稍后使用的成员变量时,我倾向于使用IllegalArgumentException。

如果是我要立即在方法中使用(解引用)的内容,我会主动抛出NullPointerException。我喜欢这种方式胜过让运行时来处理,因为我可以提供有用的信息(似乎运行时也可以做到这一点,但这是另一个话题)。

如果我正在重写一个方法,我会使用被重写方法所使用的异常类型。


-1

你应该抛出IllegalArgumentException异常,因为这会让程序员明显地意识到他已经做了一些无效的操作。开发人员习惯于看到虚拟机抛出NPE异常,以至于任何程序员都不会立即意识到自己的错误,并且会开始随意查找,或者更糟糕的是,指责你的代码存在“漏洞”。


4
抱歉,如果程序员在收到任何异常时随意查看周围的情况...更改异常名称并不能帮上太多忙。 - Christopher Smith

-5

如果你选择抛出NPE并且在你的方法中使用了该参数,那么显式检查null可能是多余和昂贵的。我认为虚拟机已经为你做了这件事。


运行时不会包含有意义的消息。 - mP.
实际上,这条评论可能会引起其他观点。如果程序员愿意的话,让虚拟机在 NPE 中发言,而程序员则在虚拟机之前用 IAE 发言。 - Jin Kwon
1
贵?我不认为 == null 是很贵的……此外,null 参数可以只是存储以备后用,并在方法调用后很长时间才抛出异常,使错误更难跟踪。或者您可以在使用 null 参数之前创建一个昂贵的对象,等等。早期检测似乎是一个不错的选择。 - PhiLho
1
对此答案进行负评是对硬件背后的误解。当然,硬件检查(CPU执行的)比显式检查更便宜。空指针解引用是一个特殊情况(访问进程未拥有的页面)的分段错误(SegV),由CPU/OS检查并由JRE作为特殊情况处理,抛出NullPointerException异常。 - digital_infinity

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