我有一个简单的setter方法的属性和空是不适合这个特定的属性。在这种情况下,我总是被撕裂:我应该抛出一个IllegalArgumentException,还是一个NullPointerException?从javadocs来看,两者都很合适。是否存在某种公认的标准?或者这只是其中一件事,你应该做任何你喜欢做的事情,两种都是正确的?
当前回答
如果它是一个“setter”,或者我要获取一个成员稍后使用的地方,我倾向于使用IllegalArgumentException。
如果它是我现在要在方法中使用(解引用)的东西,我主动抛出一个NullPointerException。我更喜欢这样做,而不是让运行时来做,因为我可以提供有用的消息(似乎运行时也可以这样做,但这是另一天的咆哮)。
如果我重写一个方法,我使用被重写的方法使用的任何东西。
其他回答
我想从其他非法参数中挑出Null参数,所以我从IAE派生了一个名为NullArgumentException的异常。甚至不需要读取异常消息,我就知道一个空参数被传递到一个方法中,并且通过读取消息,我找到了哪个参数为空。我仍然用IAE处理程序捕获NullArgumentException,但在我的日志中,我可以快速看到差异。
我倾向于遵循JDK库的设计,特别是集合和并发(Joshua Bloch, Doug Lea,这些人知道如何设计可靠的api)。不管怎样,JDK中的许多api都会主动抛出NullPointerException。
例如,Javadoc For Map。containsKey状态:
如果键为空,则@抛出NullPointerException 不允许空键(可选)。
举办自己的NPE是完全合理的。约定是在异常消息中包含为空的参数名。
模式是这样的:
public void someMethod(Object mustNotBeNull) {
if (mustNotBeNull == null) {
throw new NullPointerException("mustNotBeNull must not be null");
}
}
无论您做什么,都不要允许设置一个错误的值,并在其他代码尝试使用它时抛出异常。这使得调试成为一场噩梦。你应该始终遵循“快速失败”的原则。
如果您选择抛出NPE,并且在方法中使用参数,显式检查null可能是多余的和昂贵的。我想VM已经为你做了。
如果它是一个setter方法,并且null被传递给它,我认为抛出一个IllegalArgumentException会更有意义。NullPointerException似乎在尝试实际使用null的情况下更有意义。
如果你在使用它,它是空的,NullPointer。如果它被传入并且它为空,则为非法参数。
作为一个主观问题,这应该是封闭的,但它仍然是开放的:
这是我以前工作的地方使用的内部政策的一部分,效果非常好。这些都是我的记忆,所以我不记得确切的措辞。值得注意的是,他们没有使用受控异常,但这超出了问题的范围。他们使用的未检查异常主要分为3类。
NullPointerException:不故意抛出。npe只有在解引用空引用时才会被VM抛出。要尽一切可能的努力确保这些错误永远不会被抛出。@Nullable和@NotNull应该与代码分析工具一起使用来发现这些错误。
IllegalArgumentException:当函数的参数不符合公共文档时抛出,这样就可以根据传入的参数识别和描述错误。OP的情况就属于这一类。
IllegalStateException:当调用函数时,其实参在传递时是意外的,或者与方法所属对象的状态不兼容时抛出。
例如,在有长度的事物中使用IndexOutOfBoundsException的两个内部版本。一个是IllegalStateException的子类,在索引大于长度时使用。另一个是IllegalArgumentException的子类,用于索引为负的情况。这是因为您可以向对象添加更多的项,并且参数将是有效的,而负数永远无效。
正如我所说,这个系统工作得非常好,有人解释了为什么会有这样的区别:“根据错误的类型,你很容易就能弄清楚该怎么做。即使您无法真正找出出错的地方,也可以找出在哪里捕获错误并创建额外的调试信息。”
NullPointerException:处理Null情况或放入断言,这样NPE就不会被抛出。如果你输入的断言只是另外两种类型中的一种。如果可能,继续调试,就像断言一开始就在那里一样。
IllegalArgumentException:你的调用站点有错误。如果传入的值来自另一个函数,请查明为什么接收到不正确的值。如果传入一个参数,则会在调用堆栈中进行错误检查,直到找到没有返回预期值的函数。
您没有按照正确的顺序调用函数。如果您正在使用其中一个参数,请检查它们并抛出IllegalArgumentException描述该问题。然后,您可以在堆栈上传播腮部,直到找到问题。
不管怎样,他的观点是你只能把IllegalArgumentAssertions复制到堆栈上。您无法将illegalstateexception或nullpointerexception传播到堆栈上,因为它们与您的函数有关。
推荐文章
- Java 8接口方法中不允许“同步”的原因是什么?
- 如何找到Java堆大小和内存使用(Linux)?
- 使用Enum实现单例(Java)
- RabbitMQ与通道和连接之间的关系
- buildSessionFactory()配置方法在Hibernate中已弃用?
- Spring MVC -如何获得所有的请求参数在一个地图在Spring控制器?
- 如何在Java中按两个字段排序?
- Android -如何覆盖“后退”按钮,所以它不完成()我的活动?
- 文件之间的差异。路径中的分隔符和斜杠
- 为什么不使用异常作为常规的控制流呢?
- 在方法参数中使用NotNull注释
- Spring MVC中处理可选参数的@RequestParam
- Tomcat:如何查找正在运行的Tomcat版本?
- “java”、“javaw”和“javaws”之间有什么区别?
- 将Date对象转换为日历对象