【发布时间】:2015-07-14 08:35:20
【问题描述】:
您知道Apache Commons Validate 或Guava Preconditions 的一些不错的替代方法,在检查对象是否不为空 时会抛出IllegalArgumentException 而不是NullPointerException(Spring Assert 除外)?
我知道Javadocs 说:
应用程序应抛出此类 [NullPointerException] 的实例以指示其他 非法使用空对象。
不过,我就是不喜欢。对我来说,NPE 总是意味着我只是忘记在某处保护空引用。我的眼睛受过如此训练,我可以发现它以每秒几页的速度浏览日志,如果我这样做了,我的脑海中总是会启用错误警报。因此,将它扔到我期望 IllegalArgumentException 的地方会让我很困惑。
假设我有一颗豆子:
public class Person {
private String name;
private String phone;
//....
}
和服务方法:
public void call(Person person) {
//assert person.getPhone() != null
//....
}
在某些情况下,一个人没有电话可能没问题(我的祖母没有任何电话)。但是如果你想打电话给这样的人,对我来说,它是调用 call 方法并传递了一个 IllegalArgument。查看层次结构 - NullPointerException 甚至不是 IllegalArgumentException 的子类。它基本上告诉你 - 你再次尝试在空引用上调用 getter。
此外,已经进行了讨论,并且我完全支持this 很好的答案。所以我的问题是——我需要做这样丑陋的事情吗:
Validate.isTrue(person.getPhone() != null, "Can't call a person that hasn't got a phone");
按照我的方式,或者是否有一个库会抛出 IllegalArgumentException 进行 notNull 检查?
【问题讨论】:
-
不清楚您所说的“正确处理的情况”是什么意思。当然,这不是对
null的意外取消引用,但它相当于同一件事:正在调用一个方法,并为一个不能为null的参数传入null,这几乎是程序员的错误. -
当然,但在这种情况下,处理了 NPE(在我的解释中),不处理 IllegalArgumentException。实际上它通常是由一些 servlet 级别的异常处理程序或 smth.
-
FWIW,JDK 树立了一个非常坚定的先例,这就是 it 期望处理无效空值的方式。
-
我仍然可能想找到一个与这些期望相反的库:)
-
"将它扔到我期望 IllegalArgumentException 的地方会让我很困惑。" - 对于维护您的代码的人来说,收到 IAE 而不是 NPE 会很混乱......只需使用标准。甚至
java.util.Objects.requireNotNull& friends 也会抛出 NPE。
标签: java nullpointerexception guava apache-commons preconditions