我何时应该使用Apache Commons的Validate.isTrue,何时应该使用’assert’关键字?

我何时应该使用Apache Commons的Validate.isTrue,何时应该使用’assert’关键字?

断言可以被关闭(事实上,它们通常是这样),因此它们对于validation用户输入没有用处。

Validate.isTrue和’assert’用于完全不同的目的。

断言
Java的断言语句通常用于记录(通过断言)在什么情况下可以调用方法,以及他们的调用者之后可能期望的真实性。 可以选择在运行时检查断言,如果它们不成立,则会导致AssertionErrorexception。

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

Validate.isTrue
org.apache.commons.lang.Validate是不同的。 它提供了一组简单的JUnit方法来检查条件,如果条件不成立则抛出“IllegalArgumentException”。

它通常在公共API应该容忍错误输入时使用。 在这种情况下,它的契约可以承诺在错误输入时抛出IllegalArgumentException。 Apache Validate为实现它提供了方便的简写。

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

使用两者
但是,虽然出于不同的目的,但可以同时使用两者。 在这种情况下,合同应明确要求在某些类型的输入时引发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 )
  • Johsua Bloch。 Effective Java ,2nd ed。,Item 38.检查参数的有效性。 ( 谷歌书 )

@thilo适用于assert关键字,但考虑像Spring Assert这样的Assertion。

参见从Guava解释的ConditionalFailures 。

  • 前提条件 “你搞砸了(打电话)。”
  • 断言 “我搞砸了。”
  • validation “我依赖的人搞砸了。”