我有一个简单的setter方法的属性和空是不适合这个特定的属性。在这种情况下,我总是被撕裂:我应该抛出一个IllegalArgumentException,还是一个NullPointerException?从javadocs来看,两者都很合适。是否存在某种公认的标准?或者这只是其中一件事,你应该做任何你喜欢做的事情,两种都是正确的?
当前回答
如果它是一个setter方法,并且null被传递给它,我认为抛出一个IllegalArgumentException会更有意义。NullPointerException似乎在尝试实际使用null的情况下更有意义。
如果你在使用它,它是空的,NullPointer。如果它被传入并且它为空,则为非法参数。
其他回答
如果你不希望null是一个允许的值,似乎会调用IllegalArgumentException,如果你试图使用一个结果为null的变量,则会抛出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并不是一个足以胜过这些其他考虑因素的好理由。
我完全同意你说的话。早失败,快失败。非常好的异常咒语。
抛出哪个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。
如果它是一个“setter”,或者我要获取一个成员稍后使用的地方,我倾向于使用IllegalArgumentException。
如果它是我现在要在方法中使用(解引用)的东西,我主动抛出一个NullPointerException。我更喜欢这样做,而不是让运行时来做,因为我可以提供有用的消息(似乎运行时也可以这样做,但这是另一天的咆哮)。
如果我重写一个方法,我使用被重写的方法使用的任何东西。
推荐文章
- Java中枚举的命名:单数还是复数?
- JavaBean和POJO之间的区别是什么?
- 注释在Java中如何使用,在哪里使用?
- 如何在Ubuntu下安装JDK 11 ?
- Spring Boot -无法确定数据库类型为NONE的嵌入式数据库驱动程序类
- 如何转换/解析从字符串到字符在java?
- 如何在Android中动态更改菜单项文本
- 如何比较两个没有时间部分的日期?
- 如何在Java中找到给定类的所有子类?
- 匿名类的访问构造函数
- 从Java访问Kotlin扩展函数
- 解析LocalDateTime时无法从TemporalAccessor获取LocalDateTime (Java 8)
- 以AM/PM的12小时格式显示当前时间
- 求两个集合的差值
- Junit @Rule如何工作?