【问题标题】:When should I use Apache Commons' Validate.isTrue, and when should I just use the 'assert' keyword?什么时候应该使用 Apache Commons 的 Validate.isTrue,什么时候应该只使用 'assert' 关键字?
【发布时间】:2011-06-30 06:25:39
【问题描述】:

什么时候应该使用 Apache Commons 的 Validate.isTrue,什么时候应该只使用 'assert' 关键字?

【问题讨论】:

标签: java validation assert apache-commons


【解决方案1】:

Validate.isTrue 和 'assert' 的用途完全不同。

断言
Java 的断言语句通常用于记录(通过 断言)在什么情况下可以调用方法,以及 他们的来电者可以期待之后的真实情况。断言可以 可选地在运行时检查,导致 AssertionError 如果不持有则例外。

就按合同设计而言,断言可用于定义 前置条件和后置条件以及类不变量。如果在运行时 这些被检测到不成立,这指向设计或实现 系统问题。

Validate.isTrue
org.apache.commons.lang.Validate 不同。它提供了一个简单的集合 类似 JUnit 的方法,它们检查条件并抛出 如果条件不成立,则为“IllegalArgumentException”。

它通常在公共 API 应该容忍不良的情况下使用 输入。在这种情况下,它的合约可以承诺抛出一个 输入错误时出现 IllegalArgumentException。 Apache Validate 提供 实现这一点的便捷简写。

由于抛出了 IllegalArgumentException,所以没有意义 使用 Apache 的 Validate 来检查后置条件或不变量。 同样,使用 'assert' 进行用户输入验证是不正确的, 因为可以在运行时禁用断言检查。

同时使用
但是,可以同时使用两者,尽管 用于不同的目的。在这种情况下,合同应明确 要求在某些类型上引发 IllegalArgumentException 的输入。然后通过 Apache Validate 实现。 然后也简单地断言不变量和后置条件 作为可能的附加前提条件(例如影响 对象的状态)。例如:

public int m(int n) {
  // the class invariant should hold upon entry;
  assert this.invariant() : "The invariant should hold.";

  // a precondition in terms of design-by-contract
  assert this.isInitialized() : "m can only be invoked after initialization.";

  // Implement a tolerant contract ensuring reasonable response upon n <= 0:
  // simply raise an illegal argument exception.
  Validate.isTrue(n > 0, "n should be positive");

  // the actual computation.
  int result = complexMathUnderTrickyCircumstances(n);

  // the postcondition.
  assert result > 0 : "m's result is always greater than 0.";
  assert this.processingDone() : "processingDone state entered after m.";
  assert this.invariant() : "Luckily the invariant still holds as well.";

  return result;
}

更多信息:

  • Bertrand Meyer,“按合同应用设计”,IEEE 计算机,1992 年 (pdf)
  • 约苏亚·布洛赫。 Effective Java,第 2 版,第 38 条。检查参数的有效性。 (google books)

【讨论】:

  • 约苏亚·布洛赫。 Effective Java,第 23 条:检查参数的有效性。
【解决方案2】:

断言可以关闭(事实上,它们通常是关闭的),因此它们对于验证用户输入没有用处,例如。

【讨论】:

    【解决方案3】:

    @thilo 适合 assert 关键字,但请考虑像 spring Assert 这样的 Assertion。

    见来自 Guava 的 ConditionalFailuresExplained

    • 前提条件“你搞砸了(来电者)。”
    • 断言“我搞砸了。”
    • 验证“我依赖的人搞砸了。”

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-09-11
      • 1970-01-01
      • 2023-04-02
      • 2011-04-15
      • 2017-04-10
      • 2012-03-19
      • 2018-05-12
      • 2018-12-11
      相关资源
      最近更新 更多