我有一个简单的setter方法的属性和空是不适合这个特定的属性。在这种情况下,我总是被撕裂:我应该抛出一个IllegalArgumentException,还是一个NullPointerException?从javadocs来看,两者都很合适。是否存在某种公认的标准?或者这只是其中一件事,你应该做任何你喜欢做的事情,两种都是正确的?
当前回答
作为一个主观问题,这应该是封闭的,但它仍然是开放的:
这是我以前工作的地方使用的内部政策的一部分,效果非常好。这些都是我的记忆,所以我不记得确切的措辞。值得注意的是,他们没有使用受控异常,但这超出了问题的范围。他们使用的未检查异常主要分为3类。
NullPointerException:不故意抛出。npe只有在解引用空引用时才会被VM抛出。要尽一切可能的努力确保这些错误永远不会被抛出。@Nullable和@NotNull应该与代码分析工具一起使用来发现这些错误。
IllegalArgumentException:当函数的参数不符合公共文档时抛出,这样就可以根据传入的参数识别和描述错误。OP的情况就属于这一类。
IllegalStateException:当调用函数时,其实参在传递时是意外的,或者与方法所属对象的状态不兼容时抛出。
例如,在有长度的事物中使用IndexOutOfBoundsException的两个内部版本。一个是IllegalStateException的子类,在索引大于长度时使用。另一个是IllegalArgumentException的子类,用于索引为负的情况。这是因为您可以向对象添加更多的项,并且参数将是有效的,而负数永远无效。
正如我所说,这个系统工作得非常好,有人解释了为什么会有这样的区别:“根据错误的类型,你很容易就能弄清楚该怎么做。即使您无法真正找出出错的地方,也可以找出在哪里捕获错误并创建额外的调试信息。”
NullPointerException:处理Null情况或放入断言,这样NPE就不会被抛出。如果你输入的断言只是另外两种类型中的一种。如果可能,继续调试,就像断言一开始就在那里一样。
IllegalArgumentException:你的调用站点有错误。如果传入的值来自另一个函数,请查明为什么接收到不正确的值。如果传入一个参数,则会在调用堆栈中进行错误检查,直到找到没有返回预期值的函数。
您没有按照正确的顺序调用函数。如果您正在使用其中一个参数,请检查它们并抛出IllegalArgumentException描述该问题。然后,您可以在堆栈上传播腮部,直到找到问题。
不管怎样,他的观点是你只能把IllegalArgumentAssertions复制到堆栈上。您无法将illegalstateexception或nullpointerexception传播到堆栈上,因为它们与您的函数有关。
其他回答
一般来说,开发人员不应该抛出NullPointerException异常。当代码试图解引用值为null的变量时,运行时将引发此异常。因此,如果你的方法想要显式禁止null,而不是恰好有一个空值引发一个NullPointerException,你应该抛出一个IllegalArgumentException。
这是一个“圣战”式的问题。换句话说,两种选择都是好的,但人们会有自己的偏好,他们会誓死捍卫这些偏好。
如果它是一个“setter”,或者我要获取一个成员稍后使用的地方,我倾向于使用IllegalArgumentException。
如果它是我现在要在方法中使用(解引用)的东西,我主动抛出一个NullPointerException。我更喜欢这样做,而不是让运行时来做,因为我可以提供有用的消息(似乎运行时也可以这样做,但这是另一天的咆哮)。
如果我重写一个方法,我使用被重写的方法使用的任何东西。
我完全同意你说的话。早失败,快失败。非常好的异常咒语。
抛出哪个Exception主要是个人喜好的问题。在我看来,IllegalArgumentException似乎比使用NPE更具体,因为它告诉我问题是我传递给方法的参数,而不是执行方法时可能生成的值。
我的2美分
一些集合假设使用NullPointerException而不是IllegalArgumentException拒绝null。例如,如果你比较一个包含null的集合和一个拒绝null的集合,第一个集合将调用另一个集合的containsAll,并捕获它的NullPointerException——而不是IllegalArgumentException。(我正在查看AbstractSet.equals的实现。)
You could reasonably argue that using unchecked exceptions in this way is an antipattern, that comparing collections that contain null to collections that can't contain null is a likely bug that really should produce an exception, or that putting null in a collection at all is a bad idea. Nevertheless, unless you're willing to say that equals should throw an exception in such a case, you're stuck remembering that NullPointerException is required in certain circumstances but not in others. ("IAE before NPE except after 'c'...")
类似地,构建工具可以自动插入空检查。值得注意的是,Kotlin的编译器在向Java API传递可能为空的值时执行此操作。当检查失败时,结果是NullPointerException。因此,为了给所有的Kotlin用户和Java用户提供一致的行为,您需要使用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