Утверждения Java используются недостаточно


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

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

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

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

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

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

10 ответов:

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

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

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

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

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

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

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

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

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

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

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

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

yc

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

Если вы включите ФА.банку в вашем classpath при компиляции кода Java он будет делать свою магию, а затем скажет

Note: %n assertions inlined.

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

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

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

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

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

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

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

  • поймать ошибки программирования рано
  • код документа с помощью кода

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

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

Оставьте Утверждения Включенными

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

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

на самом деле они прибыли в Java 1.4

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

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

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

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

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

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

выход будет выглядеть так:

java.lang.NullPointerException: name may not be null