前提条件库为notNull检查抛出IllegalArgumentException

mac*_*ias 7 java nullpointerexception apache-commons preconditions guava

您是否知道Apache Commons ValidateGuava Preconditions的一些不错的替代方案,当检查对象是否为null(Spring Assert除外)时会抛出IllegalArgumentException而不是NullPointerException ?


我知道Javadocs说:

应用程序应抛出此类的实例[NullPointerException]以指示null对象的其他非法使用.

不过,我只是不喜欢它.对我来说,NPE总是意味着我只是忘了在某个地方获得null引用.我的眼睛是如此受过训练,我可以发现它以每秒几页的速度浏览日志,如果我这样做,那么我的头脑中始终会启用bug警报.因此,如果将它抛到我期望IllegalArgumentException的位置,那将是非常令人困惑的.

说我有一个豆子:

public class Person {
  private String name;
  private String phone;
  //....
}
Run Code Online (Sandbox Code Playgroud)

和服务方法:

public void call(Person person) {
  //assert person.getPhone() != null
  //....
}
Run Code Online (Sandbox Code Playgroud)

在某些情况下,一个人没有电话可能没问题(我的奶奶不拥有任何电话).但是如果你想打电话给这样的人,对我而言,它会调用带有IllegalArgument调用方法.查看层次结构 - NullPointerException甚至不是IllegalArgumentException的子类.它基本上告诉你 - 再次尝试在null引用上调用getter.

此外,已经有讨论,我完全支持这个很好的答案.所以我的问题只是 - 我是否需要像这样做丑陋的事情:

Validate.isTrue(person.getPhone() != null, "Can't call a person that hasn't got a phone");
Run Code Online (Sandbox Code Playgroud)

有我的方式,或者是否有一个库只会抛出IllegalArgumentException进行notNull检查?

Fri*_*rdt 8

由于这个问题的主题演变为"正确使用IllegalArgumentException和NullpointerException",我想指出有效Java项目60(第二版)中的海峡前瞻性答案:

可以说,所有错误的方法调用都归结为非法参数或非法状态,但其他例外标准地用于某些类型的非法参数和状态.如果调用者在某些禁止空值的参数中传递null,则约定表示抛出NullPointerException而不是IllegalArgumentException.类似地,如果调用者将表示索引的参数中的超出范围的值传递给序列,则应抛出IndexOutOfBoundsException而不是IllegalArgumentException.


Cap*_*Man 5

怎么样PreconditionscheckArgument

public void call(Person person) {
    Preconditions.checkArgument(person.getPhone() != null);
    // cally things...
}
Run Code Online (Sandbox Code Playgroud)

checkArgument throws IllegalArgumentException而不是NullPointerException.

  • @macias `NullPointerException` 通常被推荐用于 null 参数而不是 `IllegalArgumentException`(参见 _Effective Java_ Item 60 [as above](/sf/answers/2112067331/))。它在标准库中也很常见,例如在 [URI.create()](https://docs.oracle.com/javase/7/docs/api/java/net/URI.html#create(java.lang 。细绳))。这与为 [List.get()](https://docs.oracle.com/javase/7/docs/api/java/util/List. html#get(int)) -- 更具体,错误往往由于特定原因而出现。 (2认同)