Java 在NullPointerException和IllegalArgumentException之间进行选择,以在对象构造时发送错误信号

Java 在NullPointerException和IllegalArgumentException之间进行选择,以在对象构造时发送错误信号,java,exception,nullpointerexception,Java,Exception,Nullpointerexception,我有一个关于Java最佳实践的问题。我正在编写一个类,它在构造时非常依赖对象。事实上,如果在构造时传入的对象为null,则大多数功能都没有意义。我认为最好在对象构造时将null作为参数传递的情况下抛出异常,但我不知道在这种情况下最合适的异常是什么。我应该抛出null指针、IllegalArgument、Instatiation,甚至是初始化异常吗 我在Java源代码库中看到了所有这些代码,但我似乎无法区分为什么在某些情况下使用空指针,而在其他情况下使用IllegalArgument。我个人认为,

我有一个关于Java最佳实践的问题。我正在编写一个类,它在构造时非常依赖对象。事实上,如果在构造时传入的对象为null,则大多数功能都没有意义。我认为最好在对象构造时将null作为参数传递的情况下抛出异常,但我不知道在这种情况下最合适的异常是什么。我应该抛出null指针、IllegalArgument、Instatiation,甚至是初始化异常吗

我在Java源代码库中看到了所有这些代码,但我似乎无法区分为什么在某些情况下使用空指针,而在其他情况下使用IllegalArgument。我个人认为,如果在构造时传入一个错误的参数,就会出现一些初始化错误。

首先,您应该绝对抛出一个异常。这是正确的做法

至于您是否应该抛出
IllegalArgumentException
NullPointerException
,Josh Bloch在有效的Java中谈到了这一点,并普遍认为
NullPointerException
是一个合理的选择。我不完全确定我是否同意(我可能会选择
IllegalArgumentException
),但最终这并不重要:您不应该直接捕获这两个异常中的任何一个,堆栈跟踪将告诉您哪里存在问题

(遗憾的是,Java没有与.NET完全相同的版本,这意味着它听起来像什么。)

就我个人而言,我是番石榴的超级粉丝:

(有时用于静态导入
checkNotNull

首先,您应该绝对抛出异常。这是正确的做法

至于您是否应该抛出
IllegalArgumentException
NullPointerException
,Josh Bloch在有效的Java中谈到了这一点,并普遍认为
NullPointerException
是一个合理的选择。我不完全确定我是否同意(我可能会选择
IllegalArgumentException
),但最终这并不重要:您不应该直接捕获这两个异常中的任何一个,堆栈跟踪将告诉您哪里存在问题

(遗憾的是,Java没有与.NET完全相同的版本,这意味着它听起来像什么。)

就我个人而言,我是番石榴的超级粉丝:


(有时与静态导入
checkNotNull
一起使用)

NullPointerException
用于期望有效对象但获得
null
的情况。当试图调用
null
对象上的方法时,这一点尤其重要。这是它最常用的用法。然而,你的情况也可能证明这一点

IllegalArgumentException
是在您接收到一个方法的参数时使用的,该参数不是您所期望的,或者是错误的类型/样式/等等。在我看来,这在您的情况下更合适。您需要一个有效的对象,但收到的参数是
null
。此参数值无效-因此我将抛出
IllegalArgumentException
,并在异常消息中指定错误,例如:

public MyClass(InputObject obj) {
    if(obj == null) {
        throw new IllegalArgumentException("null passed to MyClass constructor");
    }

    ...
}

NullPointerException
用于期望有效对象但得到
null
的情况。当试图调用
null
对象上的方法时,这一点尤其重要。这是它最常用的用法。然而,你的情况也可能证明这一点

IllegalArgumentException
是在您接收到一个方法的参数时使用的,该参数不是您所期望的,或者是错误的类型/样式/等等。在我看来,这在您的情况下更合适。您需要一个有效的对象,但收到的参数是
null
。此参数值无效-因此我将抛出
IllegalArgumentException
,并在异常消息中指定错误,例如:

public MyClass(InputObject obj) {
    if(obj == null) {
        throw new IllegalArgumentException("null passed to MyClass constructor");
    }

    ...
}

IllegalArgument向使用代码的开发人员清楚地说明了问题所在以及如何解决问题。它还清楚地表明,如果没有该对象,该方法将无法工作


NullPointer意味着他们必须考虑一下问题是什么(不是很多),可能意味着代码更干净,但正如我上面所说的。从文档的角度来看,您的代码是否可以使用空值还不清楚。

IllegalArgument向使用代码的开发人员清楚地说明了问题所在以及如何解决问题。它还清楚地表明,如果没有该对象,该方法将无法工作


NullPointer意味着他们必须考虑一下问题是什么(不是很多),可能意味着代码更干净,但正如我上面所说的。从文档的角度来看,目前还不清楚您的代码是否可以使用空值工作。

如果您认为平台异常没有为客户端提供足够的信息来理解和解决问题,您可以创建自己的异常,在这方面更合适,比如说.NET的
ArgumentNullException
;这将告诉客户端问题是什么,以及如何解决问题。如果您认为平台异常没有为客户端提供正确的信息来理解和解决问题,您可以创建自己的异常,在这方面更合适,比如说.NET的
ArgumentNullException
;这将告诉客户端问题是什么,以及如何解决问题。如果你对对象做了什么,Java将抛出NPE本身。非常正确,Mong,但我想立即告诉客户端。这将在运行时隐藏错误之前捕获所有错误。如果您正在对ob执行任何操作