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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5049163/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 09:10:23  来源:igfitidea点击:

When should I use Apache Commons' Validate.isTrue, and when should I just use the 'assert' keyword?

javavalidationassertapache-commons

提问by Kyle

When should I use Apache Commons' Validate.isTrue, and when should I just use the 'assert' keyword?

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

采纳答案by Thilo

Assertions can be turned off (in fact, they normally are), so they are not useful for validating user input, for example.

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

回答by avandeursen

Validate.isTrue and 'assert' serve completely different purposes.

Validate.isTrue 和 'assert' 服务于完全不同的目的。

assert
Java's assert statements are typically used for documenting (by means of assertions) under what circumstances methods can be invoked, and what their callers can expect to be true afterward. The assertions can optionally be checked at run time, resulting in an AssertionError exception if they don't hold.

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

In terms of design-by-contract, assertions can be used to define pre- and postconditions as well as class invariants. If at run time these are detected not to hold, this points to a design or implementation problem in the system.

就契约式设计而言,断言可用于定义前置条件和后置条件以及类不变量。如果在运行时检测到这些不成立,则表明系统中存在设计或实现问题。

Validate.isTrue
org.apache.commons.lang.Validate is different. It offers a simple set of JUnit-like methods which check a condition, and throw an "IllegalArgumentException" if the condition does not hold.

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

It is typically used when a public API should be tolerant against bad input. In that case, its contract can promise to throw an IllegalArgumentException upon erroneous input. Apache Validate offers a convenient shorthand for implementing this.

它通常用于公共 API 应该容忍错误输入的情况。在这种情况下,它的合约可以承诺在错误输入时抛出 IllegalArgumentException。Apache Validate 为实现这一点提供了一个方便的速记。

Since an IllegalArgumentException is thrown, it does not make sense to use Apache's Validate to check postconditions or invariants. Likewise, it is incorrect to use 'assert' for user input validation, since assertion checking can be disabled at run time.

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

Using both
It is possible, though, to use both at the same time, albeit for different purposes. In this case, the contract should explicitly require IllegalArgumentException to be raised upon certain types of input. This is then implemented via Apache Validate. Invariants and postconditions are then simply asserted, as well as possible additional preconditions (for example affecting the state of the object). For example:

两者
同时使用不过,可以同时使用两者,尽管用途不同。在这种情况下,合同应明确要求在某些类型的输入上引发 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;
}

More information:

更多信息:

  • Bertrand Meyer, "Applying Design by Contract", IEEE Computer, 1992 (pdf)
  • Johsua Bloch. Effective Java, 2nd ed., Item 38. Check parameters for validity. (google books)
  • Bertrand Meyer,“按合同应用设计”,IEEE 计算机,1992 ( pdf)
  • 约书亚·布洛赫。Effective Java,第 2 版,第 38 项。检查参数的有效性。(谷歌图书

回答by Anderson

@thilo is right for assert keyword, but consider about Assertion like spring Assert.

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

See ConditionalFailuresExplainedfrom Guava.

请参阅来自 Guava 的ConditionalFailuresExplained

  • Precondition"You messed up (caller)."
  • Assertion"I messed up."
  • Verification"Someone I depend on messed up."
  • 前提条件“你搞砸了(来电者)。”
  • 断言“我搞砸了。”
  • 验证“我依赖的人搞砸了。”