当前位置: 首页 > 知识库问答 >
问题:

为notNull检查引发IllegalArgumentException的前提条件库

吕利
2023-03-14

您知道Apache Commons Validate或Guava前置条件的一些不错的替代方法吗?它们在检查对象是否为null(Spring Assert除外)时会抛出IllegalArgumentException而不是NullPointerException?

我知道Javadocs说:

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

然而,我就是不喜欢它。对我来说,NPE总是意味着我忘了在某个地方保护空引用。我的眼睛是如此训练有素,我可以发现它以每秒几页的速度浏览日志,如果我这样做了,我的脑袋里总是有bug警报。因此,对于我来说,将它抛出到我期望的非法argargumentexception的地方是相当混乱的。

假设我有一颗豆子:

public class Person {
  private String name;
  private String phone;
  //....
}

以及一种服务方法:

public void call(Person person) {
  //assert person.getPhone() != null
  //....
}

在某些情况下,一个人没有电话(我奶奶没有电话)也没关系。但是,如果您想调用这样的人,对我来说,它调用call方法时传递了一个IllegalArgument。看看层次结构——NullPointerException甚至不是IllegalArgumentException的子类。它基本上告诉您——您再次尝试调用null引用上的getter。

此外,已经有讨论,有一个很好的答案我完全支持。所以我的问题是——我需要做这样丑陋的事情吗:

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

按照我的方式,还是有一个库只会抛出IllegalArgumentException进行notNull检查?

共有3个答案

涂选
2023-03-14

您可以将valid4j与hamcrest matchers一起使用(可以在Maven Central上找到org.valid4j:valid4j)。“Validation”类支持常规输入验证(即抛出可恢复异常):

import static org.valid4j.Validation.*;

validate(argument, isValid(), otherwiseThrowing(InvalidException.class));

链接:

  • http://www.valid4j.org/
  • https://github.com/valid4j/valid4j

另一方面:该库还支持前置和后置条件(如断言),并且可以注册您自己的自定义全局策略(如果需要):

import static org.valid4j.Assertive.*;

require(x, greaterThan(0)); // throws RequireViolation extends AssertionError
...
ensure(r, notNullValue()); // throws EnsureViolation extends AssertionError
徐承载
2023-03-14

那么先决条件检查参数呢?

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

check Argument抛出IllegalArgumentExc0019而不是NullPointerExc0019

郑浩博
2023-03-14

由于这个问题的主题演变成“IllegalArgumentExcema和NullpointerExcema的正确用法”,我想指出有效Java第60项(第二版)中的海峡前瞻答案:

可以说,所有错误的方法调用都归结为非法参数或非法状态,但其他异常标准地用于某些非法参数和状态。若调用者在某个参数中传递null,而该参数的null值是被禁止的,那个么按照惯例,将抛出NullPointerException而不是IllegalArgumentException。类似地,如果调用方将表示索引的参数中的out-ofrange值传递到序列中,则应引发IndexOutOfBoundsException,而不是IllegalArgumentException。

 类似资料:
  • 我想备份我的应用程序的房间数据库。我试图使用获取数据库的uri,但它在这一行抛出了IAE: 在我有这个提供者标签: 如下所示: 错误: 如下所示:

  • 问题内容: 我正在尝试学习pthread_cond_wait的基础知识。在所有用法中,我都可以看到 要么 我的问题是,我们只想cond_wait因为条件为假。那我为什么要忍受明确地放置一个if / while循环的痛苦。我可以理解,在不进行任何if / while检查的情况下,我们将直接击中它,根本不会返回。条件检查是仅用于解决此目的,还是具有其他意义。如果它用于解决不必要的条件等待,则进行条件检

  • 公共方法的先决条件和后决条件构成了该方法与其客户之间的合同。 1.根据,调用者不应该验证后置和被调用的方法不应该验证先决条件: 让我们回顾一下平方根函数sqrt的前提和后置,如程序49.2所示。调用sqrt的函数负责向函数传递一个非负数。如果传递了一个负数,平方根函数应该什么都不做来处理它。另一方面,如果一个非负数被传递给sqrt,sqrt有责任传递一个满足后置的结果。因此,调用sqrt的人不应该

  • 问题内容: 我正在尝试实现自己的自定义SurfaceView,当其被触摸时,会在用户触摸屏幕的位置绘制一个圆圈。但是,当我打电话时,我得到了一个例外。每当画布锁定时,都会出现非法论点。示例代码发布在下面。 以下是我不断收到的错误日志: 帮助将不胜感激。 问题答案: 在画布上绘制后,需要将其解锁。正确的安全性是: 得到画布调用mSurfaceHolder.lockCanvas(); 在画布上画画。

  • 我想在我的项目中使用Jetbrains@nullable/@notnull注释。 我有一个具有@NotNull字段的类。构造函数自然不接受,而是抛出异常。当然,这个构造函数的参数也是用@NotNull注释的。 为什么IntelliJ IDEA抱怨空检查?文件指出: 带NotNull注释的元素声明null值被禁止返回(对于方法)、传递(参数)和保留(局部变量和字段)。 但是我仍然必须在运行时检查nu

  • 我想进行更新,但我想添加的条件检查不是基于主表的哈希/范围,而是基于GSI。 实际上,如果给定属性(即GSI的哈希)已经存在,我希望保存失败。 例如,在一个虚构的employees表中,“SSN”是散列键,“EmployeeId”上有一个GSI。这两个属性都必须是独一无二的。在保存员工时,我希望确保表中没有使用“SSN”或“EmployeeId”。我可以用表的散列,也就是SSN,但不能用GSI的散