Это хорошая практика, чтобы использовать assert в Java? - PullRequest
27 голосов
/ 27 декабря 2010

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

РЕДАКТИРОВАТЬ : я знаю, что утверждения в целом это хорошая практика. Мой вопрос, чтобы быть более точным, если в Java BKM утверждения использует ключевое слово assert, а не исключение, ведение журнала и другие методы.

Ответы [ 11 ]

24 голосов
/ 27 декабря 2010

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

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

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

13 голосов
/ 07 апреля 2012

Когда я писал на C ++, я использовал утверждения гораздо больше, чем на Java.Я использую их не так часто, потому что они мне не нужны так часто, как раньше.Многие из ошибок C ++, которые я бы попытался уловить с помощью утверждений, больше не являются проблемой в Java.

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

Мой ответ на оба вопроса одинаков.Утверждения не должны отлавливать случаи, которые вы ожидаете увидеть в работающем приложении.Целью утверждений является выявление ошибок.Вы должны использовать их только там, где единственный способ «обработать» их - вернуться и исправить код.Вот почему они не генерируют исключения - вы не хотите, чтобы они были частью вашей общей обработки исключений.

Что касается их включения, моя IDE по умолчанию настроена на их включение.Итак, для внутреннего тестирования я всегда знаю, что они включены.

Вот пример, где единственное, что нужно использовать - assert: я работал над большим проектом Swing, где первоначальные кодеры не понимали этого.пользовательский интерфейс может быть обновлен только из потока событий, что привело к всевозможным ошибкам.Поэтому я вставил это утверждение во многих местах, где все было странно: assert EventQueue.isDispatchThread ();Если это утверждение сработало, мы работали не с того потока, и разработчики должны были быть уведомлены, чтобы они могли переместить код в нужный поток.Нет никакого способа справиться с этим в рабочем приложении.

8 голосов
/ 27 декабря 2010

Да, это странно.Эта функция была очень востребована, но после того, как она была введена в язык, ее практически никто не использует.

Я иногда использую assert в качестве инструмента комментирования.Вместо

// now it should be empty

я могу написать

assert size == 0;

Но я действительно не включил assert, поэтому утверждение никогда не проверялось.

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

4 голосов
/ 27 декабря 2010

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

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

2 голосов
/ 27 декабря 2010

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

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

Более "современный" подход - это, например, использование Google Guava с предварительными условиями . Это механизм утверждения типа библиотеки, который вы можете использовать, когда должны выполняться условия, и вы не хотите возиться с переключателями Java.

1 голос
/ 30 июня 2015

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

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

1 голос
/ 27 декабря 2010

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

For example, to prove that sort+reverse is equivalent to sort in reverse order:
Method 1: sort(int[] arr, int len)
// pre: len is the length of the array arr
// post: arr is sorted in ascending order
Method 2: reverse(int[] arr)
// post: the order of elements in arr is
// reversed (e.g. [9 5 10] -> [10 5 9])
Assertion 1: the length of arr is len
sort(arr,len);
Assertion 2: arr is sorted in ascending order
reverse(arr);
Assertion 3: the order of arr is reversed
1 голос
/ 27 декабря 2010

Ну, это действительно зависит от того, как вы на это смотрите, но это рекомендуется.

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

0 голосов
/ 24 марта 2016

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

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

Поэтому я ставлю

static { AssertionUtil.enableAssertionsForThisClass(); }

на вершину каждого класса.См http://commons.unkrig.de.

0 голосов
/ 27 декабря 2010

Это выгодно для коротких условий.Однако использование зависит от вашей практики кодирования.Потому что иногда логику лучше применить, используя assert, чем жесткими методами!

...