Java 为什么在参数为null时抛出NullPointerException?

Java 为什么在参数为null时抛出NullPointerException?,java,c#,nullpointerexception,null,Java,C#,Nullpointerexception,Null,我在Stackoverflow上多次看到这段代码: public void doStuff(Object anObject) { if (anObject == null) { throw new NullPointerException("anObject can't be null"); } //rest of the function } 这是针对null参数的保护子句,因为将null传递给要求参数为非null的函数将导致Null

我在Stackoverflow上多次看到这段代码:

public void doStuff(Object anObject) {  
    if (anObject == null) {  
        throw new NullPointerException("anObject can't be null");   
    }  
    //rest of the function
}
这是针对
null
参数的保护子句,因为将
null
传递给要求参数为非null的函数将导致
NullPointerException

我理解保护条件在其他情况下(即检查日期范围、负货币值、无效字符串大小等)验证参数的重要性

但是,在
null
的情况下,特别是
引发的
NullPointerException
不是多余的吗?这与让运行时稍后抛出
NullPointerException
本身有何不同


注意:我是以一种与语言无关的方式提问的,因为模式本身可以应用于Java和C#。

唯一的区别是它发生的时间。在代码开始修改状态之前,如果在中间抛出异常可能无效,有时可能会过早抛出异常。也就是说,抛出一个
NullPointerException
,这似乎是一个糟糕的做法;最好抛出一个
IllegalArgumentException
。编辑:根据下面的评论,
NullPointerException
是在这种情况下建议抛出的异常,至少对Java是这样。

唯一的区别是它发生的时间。在代码开始修改状态之前,如果在中间抛出异常可能无效,有时可能会过早抛出异常。也就是说,抛出一个
NullPointerException
,这似乎是一个糟糕的做法;最好抛出一个
IllegalArgumentException
。编辑:根据下面的评论,
NullPointerException
是在这种情况下建议抛出的异常,至少对于Java是这样。

因为这个问题有C标记,我将回答C案例。在这种情况下,当您访问null指针时抛出的是
NullReferenceException
,当参数为null时通常抛出的是
ArgumentNullException
。但更重要的是,当您显式检查参数时,您:

尽可能快地抛出异常,而不是在突然访问空指针时在方法中间的某个地方。
  • 你明确地说什么是空的。在C#中,至少当抛出
    NullReferenceException
    时,您只能猜测什么是null以及在哪里
  • 由于这个问题带有C#标记,我将回答关于C#case的问题。在这种情况下,当您访问null指针时抛出的是
    NullReferenceException
    ,当参数为null时通常抛出的是
    ArgumentNullException
    。但更重要的是,当您显式检查参数时,您:

    尽可能快地抛出异常,而不是在突然访问空指针时在方法中间的某个地方。
  • 你明确地说什么是空的。在C#中,至少当抛出
    NullReferenceException
    时,您只能猜测什么是null以及在哪里

  • 这有助于尽快检测错误。该方法可能不会引发空指针异常(取决于代码的逻辑),空对象可能会在其他方法/代码中传播到其他地方并在那里引发异常,或者更糟的是,它可能会导致错误结果,从而导致一个无声的bug,该bug可能会进入最终代码

    摘自有效的Java第二版

    如果将无效的参数值传递给方法,则 在执行前检查其参数,它将快速失败并 干净,有适当的例外。如果该方法无法检查 根据它的参数,可能会发生一些事情。这种方法可能会失败 在处理过程中出现了令人困惑的异常。更糟糕的是 方法可以正常返回,但默默地计算错误的结果。 最糟糕的是,该方法可以正常返回,但会留下一些对象 处于受损状态,在系统中某个不相关的点上导致错误 代码在将来的某个不确定的时间被删除


    这有助于尽快检测错误。该方法可能不会引发空指针异常(取决于代码的逻辑),空对象可能会在其他方法/代码中传播到其他地方并在那里引发异常,或者更糟的是,它可能会导致错误结果,从而导致一个无声的bug,该bug可能会进入最终代码

    摘自有效的Java第二版

    如果将无效的参数值传递给方法,则 在执行前检查其参数,它将快速失败并 干净,有适当的例外。如果该方法无法检查 根据它的参数,可能会发生一些事情。这种方法可能会失败 在处理过程中出现了令人困惑的异常。更糟糕的是 方法可以正常返回,但默默地计算错误的结果。 最糟糕的是,该方法可以正常返回,但会留下一些对象 处于受损状态,在系统中某个不相关的点上导致错误 代码在将来的某个不确定的时间被删除


    一个更好的选择是
    无效argumentexception
    ,可能是为了避免副作用。如果参数直到方法的一半才被引用,并且该方法已经做了一些不可逆的工作,那么最好在任何损坏之前检查它?就个人而言,您应该在Java中抛出一个
    IllegalArgumentException
    。你先发制人。在某些情况下,您不会立即使用
    anObject
    ,您可以初始化一些其他对象,执行一些其他处理,然后使用它。立即扔掉可以防止所有这些毫无用处的发生。区别是什么?假设函数没有该检查,并且代码在null异常之前执行了一些不可逆的操作。。。另外,通常的情况不是
    NullPointerException
    ,而是