Когда использовать утверждение и когда использовать исключение

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

Например,

Group group=null; try{ group = service().getGroup("abc"); }catch(Exception e){ //I dont log error because I know whenever error occur mean group not found } if(group !=null) { //do something } 

Не могли бы вы указать, как здесь подходит утверждение? Должен ли я использовать утверждение?

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

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

Например, функция может делиться на 0, поэтому следует использовать исключение, но может быть использовано утверждение, чтобы проверить, что жесткий диск внезапно исчезает.

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

Обратите внимание, что if(group != null) не является утверждением, это просто условно.

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

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

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

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

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

Также вы должны прочитать статью Oracle об утверждении, чтобы увидеть больше случаев использования – или не использовать – assert.

Как общее правило:

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

Следующий код из вашего вопроса – плохой стиль и потенциально глючный

 try { group = service().getGroup("abc"); } catch (Exception e) { //i dont log error because i know whenever error occur mean group not found } 

Проблема в том, что вы НЕ знаете, что исключение означает, что группа не найдена. Также возможно, что вызов service() выкинул исключение или вернул null а затем вызвал исключение NullPointerException .

Когда вы поймаете «ожидаемое» исключение, вы должны поймать только исключение, которое вы ожидаете. Улавливая java.lang.Exception (и особенно не регистрируя его), вы затрудняете диагностику / отладку проблемы и потенциально позволяете приложению наносить больше урона.

Согласно этому документу http://docs.oracle.com/javase/6/docs/technotes/guides/language/assert.html#design-faq-general , «Утверждение assert подходит для непубличных предварительных условий, постусловий и инвариантов classов Проверка на уровне публичных предварительных условий все равно должна выполняться проверками внутри методов, которые приводят к определенным, задокументированным исключениям, таким как IllegalArgumentException и IllegalStateException. ”

Если вы хотите узнать больше о предварительном условии, постусловии и инварианте classа, проверьте этот документ: http://docs.oracle.com/javase/6/docs/technotes/guides/language/assert.html#usage-conditions . Он также содержит примеры использования утверждений.

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

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

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

Тестирование для null приведет к улову null, вызывающему проблемы, тогда как try / catch, поскольку у вас есть, будет ловить любую ошибку.

В общем, try / catch более безопасен, но немного медленнее, и вы должны быть осторожны, чтобы уловить все возможные ошибки. Поэтому я бы сказал, использовать try / catch – в один прекрасный день код getGroup может измениться, и вам может понадобиться эта большая сеть.

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

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

Поэтому использование утверждений в Java

  1. является более сжатым средством записи блока состояния / броска
  2. позволяет вам включать / выключать эти проверки с помощью параметров JVM. Обычно я оставлял эти проверки постоянно, если только они не влияют на производительность во время выполнения или имеют аналогичный штраф.

См. Раздел 6.1.2 (Утверждения против другого кода ошибки) документации Sun по следующей ссылке.

http://www.oracle.com/technetwork/articles/javase/javapch06.pdf

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

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

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

  • Отладчик Visual Studio - отображение целочисленных значений в шестнадцатеричном виде
  • Ошибка кодового знака: профиль Provisioning не найден.
  • Что означает == $ 0 (double equals dollar zero) в инструментах разработчика Chrome?
  • Codesign API Dropbox не работает в Xcode 4.6.3: «Объект кода вообще не подписан»
  • Покрытие кода, не показывающее результаты с помощью Xcode + gcov
  • Как испускать и выполнять байт-код Java во время выполнения?
  • «Взаимодействие с пользователем не разрешено», пытаясь подписать приложение OSX с использованием кода
  • Не удается получить доступ к родительским элементам при работе с аннотациями макросов
  • Можете ли вы создавать представления sql / хранимую процедуру с использованием Entity Framework 4.1 Первый подход к коду
  • В чем разница между собственным кодом, машинным кодом и кодом сборки?
  • Форматирование Литеральные параметры fragmentа кода C #
  • Interesting Posts

    Сканер никогда не закрывается

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

    API Карт Google v3 | нет данных карты

    Scala: Почему mapValues ​​создает представление и есть ли стабильные альтернативы?

    REST API DESIGN – получение ресурса через REST с разными параметрами, но с тем же шаблоном URL

    Как использовать события с кнопками Option Button на Userform

    Почему Guid.ToByteArray () упорядочивает байты так, как он делает?

    Что есть в операционной системе, отличной от ядра

    Группирование столбцов данных по общим значениям

    Как определить, что такое замораживающий проводник?

    Использование ALTER для удаления столбца, если оно существует в MySQL

    django: objective django.utils.functional.SimpleLazyObject?

    Подключение входного streamа к выходному streamу

    Ошибка Gulp: Следующие задачи не были выполнены: вы забыли обработать асинхронное завершение?

    Возвращаемый объект Mat из собственного кода в java в OpenCV

    Давайте будем гением компьютера.