Явные утверждения Java

Мне интересно, почему ключевое слово assert так мало используется в Java? Я почти никогда их не видел, но я думаю, что это отличная идея. Я, конечно же, предпочитаю краткость:

assert param != null : "Param cannot be null";

к многословию:

if (param == null) {
    throw new IllegalArgumentException("Param cannot be null");
}

Мое подозрение в том, что они недостаточно используются, потому что

  • Они прибыли относительно поздно (Java 1.4), к этому времени многие люди уже установили свой стиль/привычку программирования Java
  • Они отключены во время выполнения по умолчанию, WHY OH WHY??

Ответ 1

теоретически, для тестирования инвариантов, предположения, что должны быть истинными, чтобы код чтобы закончить правильно.

В показанном примере выполняется проверка допустимого ввода, что не является типичным использованием для утверждения, поскольку оно, как правило, предоставляется пользователем.

Утверждения обычно не используются в производственном коде, поскольку есть накладные расходы, и предполагается, что ситуации, в которых инварианты терпят неудачу, были пойманы как ошибки кодирования во время разработки и тестирования.

Ваша точка зрения о том, что они наступают "поздно" в java, также является причиной того, что они не рассматриваются более широко.

Кроме того, модульные тестовые среды допускают некоторую потребность в программных утверждениях быть внешними по отношению к тестируемому коду.

Ответ 2

Это злоупотребление утверждениями, чтобы использовать их для проверки ввода пользователя. Вызов IllegalArgumentException на недопустимый ввод более прав, поскольку он позволяет вызывающему методу поймать исключение, отобразить ошибку и сделать все, что ему нужно (запросить ввод снова, выйти, что угодно).

Если этот метод является частным методом внутри одного из ваших классов, это утверждение хорошо, потому что вы просто пытаетесь удостовериться, что вы случайно не передали ему нулевой аргумент. Вы проверяете утверждения, и когда вы проверили все пути и не вызвали это утверждение, вы можете отключить их, чтобы не тратить ресурсы на них. Они также полезны, как комментарии. assert в начале метода является хорошей документацией для сопровождающих, что они должны следовать определенным предварительным условиям, а assert в конце с postcondition документирует, что должен делать этот метод. Они могут быть столь же полезны, как и комментарии; moreso, потому что с утверждениями они фактически тестируют, что они документируют.

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

Ответ 3

От Программирование с утверждениями

По умолчанию утверждения во время выполнения отключены. Два переключателя командной строки позволяют выборочно включать или отключать утверждения.

Это означает, что если вы не имеете полного контроля над средой выполнения, вы не можете гарантировать, что код подтверждения будет даже вызван. Утверждения предназначены для использования в тестовой среде, а не для производственного кода. Вы не можете заменить обработку исключений на утверждения, потому что если пользователь запускает ваше приложение с отключенными утверждениями (по умолчанию), весь код обработки ошибок исчезает.

Ответ 4

В "Эффективной Java" Джошуа Блох предположил (в разделе "Проверить параметры для достоверности" ) (что-то вроде простого правила для принятия), для общедоступных методов мы будем проверять аргументы и вызывать необходимое исключение, если найдено недействительными и для непубличных методов (которые не отображаются, и вы, как пользователь из них, должны обеспечить их достоверность), мы можем использовать утверждение вместо этого.

YC

Ответ 5

@Don, вы разочарованы тем, что утверждение отключено по умолчанию. Я тоже был, и, таким образом, написал этот маленький плагин javac, который строит их (т.е. Выдает байт-код для if (!expr) throw Ex, а не этот глупый байт-код assert.

Если вы включите fa.jar в свой путь к классам при компиляции Java-кода, он сделает свою магию, а затем скажет

Note: %n assertions inlined.

@see http://smallwiki.unibe.ch/adriankuhn/javacompiler/forceassertions и, альтернативно, на github https://github.com/akuhn/javac

Ответ 6

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

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

Утверждения не должны использоваться для проверки условий, потому что это означает, что поведение вашего приложения отличается во время выполнения, когда утверждения включены/отключены - это кошмар!

Ответ 7

Утверждения очень ограничены: вы можете тестировать только логические условия, и вам нужно каждый раз писать код для полезного сообщения об ошибке. Сравните это с JUnit assertEquals(), который позволяет генерировать полезное сообщение об ошибке с входов и даже показывать два входа бок о бок в среде IDE в бегуне JUnit.

Кроме того, вы не можете искать утверждения в любой IDE, которую я видел до сих пор, но каждая среда IDE может искать вызовы методов.

Ответ 8

Утверждения полезны, потому что они:

  • catch Ошибки ПРОГРАММИРОВАНИЯ ранние
  • код документа с использованием кода

Думайте о них как о самооценке кода. Если они терпят неудачу, это должно означать, что ваша программа нарушена и должна прекратиться. Всегда включайте их во время модульного тестирования!

В "Прагматический программист" они даже рекомендуют разрешить им работать на производстве.

Оставлять утверждения вкл.

Используйте утверждения для предотвращения невозможности.

Обратите внимание, что утверждения бросают AssertionError, если они терпят неудачу, поэтому не попадают в catch Exception.

Ответ 9

Фактически они прибыли в Java 1.4

Я думаю, что основная проблема заключается в том, что при кодировании в среде, где вы сами не управляете параметрами jvm напрямую, как на серверах eclipse или J2EE (в обоих случаях можно изменять параметры jvm, но вам нужно глубоко искать найти, где это можно сделать), проще (я имею в виду, что это требует меньше усилий) использовать, если и исключения (или, что еще хуже, ничего не использовать).

Ответ 10

Как утверждали другие: утверждения не подходят для проверки ввода пользователя.

Если вас интересует многословие, я рекомендую вам проверить библиотеку, которую я написал: https://bitbucket.org/cowwoc/requirements/. Это позволит вам выразить эти проверки с использованием очень небольшого кода, и даже вы получите сообщение об ошибке от вашего имени:

requireThat("name", value).isNotNull();

и если вы настаиваете на использовании утверждений, вы также можете сделать это:

assertThat("name", value).isNotNull();

Результат будет выглядеть так:

java.lang.NullPointerException: name may not be null