Когда я должен использовать Apache Commons 'Validate.isTrue, и когда я должен просто использовать ключевое слово' assert '? - PullRequest
11 голосов
/ 19 февраля 2011

Когда мне следует использовать Apache Commons 'Validate.isTrue, и когда я должен просто использовать ключевое слово' assert '?

Ответы [ 3 ]

33 голосов
/ 28 марта 2011

Validate.isTrue и 'assert' служат совершенно разным целям.

assert Java-операторы assert обычно используются для документирования (посредством утверждений), при каких обстоятельствах могут быть вызваны методы, и что их вызывающие могут ожидать, чтобы быть истинным впоследствии.Утверждения могут быть дополнительно проверены во время выполнения, что приводит к исключению 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;
}

Дополнительная информация:

  • Бертран Мейер, «Применение дизайна по контракту», IEEE Computer, 1992 ( pdf )
  • Йохсуа Блох. Effective Java , 2-е изд., П. 38. Проверьте параметры на достоверность.( Google Книги )
2 голосов
/ 23 марта 2016

@ thilo подходит для ключевого слова assert, но подумайте об Assertion как о пружине Assert.

См. ConditionalFailuresExplained из Гуавы.

  • Предварительное условие"Вы напутали (звонящий)."
  • Утверждение"Я испортил."
  • Проверка"Кто-то, от кого я зависел, перепутал. "
2 голосов
/ 19 февраля 2011

Утверждения можно отключить (на самом деле они обычно есть), поэтому они бесполезны, например, для проверки ввода пользователя

...