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

Kyl*_*yle 11 java validation assert apache-commons

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

ava*_*sen 33

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;
}
Run Code Online (Sandbox Code Playgroud)

更多信息:

  • Bertrand Meyer,"按合同设计",IEEE计算机,1992年(pdf)
  • Johsua Bloch.Effective Java,2nd ed.,Item 38.检查参数的有效性.(谷歌书)


Thi*_*ilo 6

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