我有一个简单的setter方法的属性和空是不适合这个特定的属性。在这种情况下,我总是被撕裂:我应该抛出一个IllegalArgumentException,还是一个NullPointerException?从javadocs来看,两者都很合适。是否存在某种公认的标准?或者这只是其中一件事,你应该做任何你喜欢做的事情,两种都是正确的?
当前回答
在这种情况下,IllegalArgumentException使用API向用户传达了“不应该为空”的明确信息。正如其他论坛用户指出的那样,只要你使用API向用户传达正确的信息,你就可以使用NPE。
GaryF和tweak放弃了“有效Java”(我发誓)的参考,建议使用NPE。看看其他好的API是如何构造的,这是了解如何构造你的API的最好方法。
Another good example is to look at the Spring APIs. For example, org.springframework.beans.BeanUtils.instantiateClass(Constructor ctor, Object[] args) has a Assert.notNull(ctor, "Constructor must not be null") line. org.springframework.util.Assert.notNull(Object object, String message) method checks to see if the argument (object) passed in is null and if it is it throws a new IllegalArgumentException(message) which is then caught in the org.springframework.beans.BeanUtils.instantiateClass(...) method.
其他回答
如果它是一个“setter”,或者我要获取一个成员稍后使用的地方,我倾向于使用IllegalArgumentException。
如果它是我现在要在方法中使用(解引用)的东西,我主动抛出一个NullPointerException。我更喜欢这样做,而不是让运行时来做,因为我可以提供有用的消息(似乎运行时也可以这样做,但这是另一天的咆哮)。
如果我重写一个方法,我使用被重写的方法使用的任何东西。
你应该使用IllegalArgumentException (IAE),而不是NullPointerException (NPE),原因如下:
首先,NPE JavaDoc显式地列出了适用于NPE的情况。请注意,当不恰当地使用null时,所有这些都是由运行时抛出的。相比之下,IAE JavaDoc再清楚不过了:“抛出是为了表明一个方法被传递了一个非法或不适当的参数。”没错,就是你!
其次,当您在堆栈跟踪中看到NPE时,您会假设什么?可能有人解引用了一个null。当您看到IAE时,您假定堆栈顶部的方法调用方传递了一个非法值。同样,后一种假设是正确的,前一种假设具有误导性。
第三,由于IAE显然是为验证参数而设计的,因此必须假设它是默认的异常选择,那么为什么要选择NPE呢?当然不是针对不同的行为——你真的期望调用代码分别捕获NPE和IAE,并因此做一些不同的事情吗?您是否试图传达更具体的错误消息?但是无论如何,您都可以在异常消息文本中这样做,就像处理所有其他不正确的参数一样。
第四,其他所有不正确的参数数据都会被IAE,为什么不一致呢?为什么非法null是如此特殊,以至于它应该从所有其他类型的非法参数中获得一个单独的异常?
最后,我接受其他答案给出的论点,即Java API的某些部分以这种方式使用NPE。然而,从异常类型到命名约定,Java API与所有内容都不一致,因此我认为仅仅盲目地复制(您最喜欢的部分)Java API并不是一个足以胜过这些其他考虑因素的好理由。
标准是抛出NullPointerException。通常不会出错的“有效Java”在第42项(第一版)、第60项(第二版)或第72项(第三版)中简要讨论了这一点。“赞成使用标准异常”:
可以说,都是错误的方法 调用归结为非法 争论或非法国家,但其他 异常通常用于 一些不合法的论点 州。如果调用方传入null 某个参数,其值为空 是被禁止的吗 NullPointerException被抛出 而不是IllegalArgumentException。”
二分法……它们不重叠吗?只有整体中不重叠的部分才能构成二分法。在我看来:
throw new IllegalArgumentException(new NullPointerException(NULL_ARGUMENT_IN_METHOD_BAD_BOY_BAD));
如果你不希望null是一个允许的值,似乎会调用IllegalArgumentException,如果你试图使用一个结果为null的变量,则会抛出NullPointerException。
推荐文章
- 在流中使用Java 8 foreach循环移动到下一项
- 访问限制:'Application'类型不是API(必需库rt.jar的限制)
- 用Java计算两个日期之间的天数
- 如何配置slf4j-simple
- 在Jar文件中运行类
- 带参数的可运行?
- 我如何得到一个字符串的前n个字符而不检查大小或出界?
- 我可以在Java中设置enum起始值吗?
- Java中的回调函数
- c#和Java中的泛型有什么不同?和模板在c++ ?
- 在Java中,流相对于循环的优势是什么?
- Jersey在未找到InjectionManagerFactory时停止工作
- 在Java流是peek真的只是调试?
- Recyclerview不调用onCreateViewHolder
- 将JSON字符串转换为HashMap