Когда использовать утверждение и когда использовать исключение
В большинстве случаев я буду использовать исключение, чтобы проверить условие в моем коде, интересно, когда подходящее время для использования утверждения?
Например,
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
}
Не могли бы вы указать, как здесь подходит утверждение? Должен ли я использовать утверждение?
Похоже, я никогда не использую утверждения в производственном коде и вижу только утверждения в модульных тестах. Я знаю, что в большинстве случаев я могу просто использовать исключение для проверки, как указано выше, но я хочу знать подходящий способ сделать это "профессионально".
Ответы
Ответ 1
Утверждения должны использоваться для проверки того, что никогда не должно происходить, в то время как исключение должно использоваться для проверки того, что может произойти.
Например, функция может делиться на 0, поэтому следует использовать исключение, но можно использовать утверждение, чтобы проверить, что жесткий диск внезапно исчезает.
Утверждение остановит выполнение программы, но исключение позволит продолжить работу программы.
Обратите внимание, что if(group != null)
не является утверждением, которое является условным.
Ответ 2
Из моего ума (список может быть неполным и слишком длинным, чтобы вписаться в комментарий), я бы сказал:
- использовать исключения при проверке параметров, переданных общедоступным или защищенным методам и конструкторам.
- использовать исключения при взаимодействии с пользователем или когда вы ожидаете восстановления кода клиента из исключительной ситуации.
- использовать исключения для устранения проблем, которые могут возникнуть.
- использовать утверждения при проверке предварительных условий, пост-условий и инвариантов частного/внутреннего кода
- использовать утверждения для предоставления обратной связи себе или вашей команде разработчиков.
- используйте утверждения при проверке того, что очень маловероятно, иначе это означает, что в вашем приложении есть серьезная проблема.
- использовать утверждения для указания вещей, которые вы (предположительно) знаете как истинные
Другими словами, исключения определяют надежность вашего приложения, в то время как утверждения определяют его правильность.
Утверждения рассчитаны на то, чтобы быть дешевыми для записи, вы можете использовать их почти везде, и я использую это правило: чем больше утверждение утверждения выглядит глупо, тем более ценным оно является и тем больше информации, которую он вкладывает. При отладке программы, которая не ведет себя правильно, вы наверняка проверите более очевидные возможности сбоя на основе вашего опыта. Затем вы будете проверять проблемы, которые просто не могут произойти: это точно, когда утверждения помогают много и экономят время.
Ответ 3
Помните, что утверждения можно отключить во время выполнения с использованием параметров, а отключены по умолчанию, поэтому не рассчитывайте на них, кроме как для целей отладки.
Также вы должны прочитать статью Oracle об утверждении, чтобы увидеть больше случаев, когда использовать или не использовать - утверждать.
Ответ 4
Как правило:
- Используйте утверждения для внутренних проверок согласованности, где это не имеет значения, если кто-то отключит их. (Обратите внимание, что команда
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
(и особенно, не регистрируя его), вы затрудняете диагностику/отладку проблемы и потенциально позволяете приложению наносить больше урона.
Ответ 5
Ну, еще в Microsoft, рекомендация заключалась в том, чтобы выкидывать исключения во всех API, которые вы публикуете публично, и использовать Asserts во всех возможных предположениях, которые вы делаете о внутреннем коде. Это немного свободное определение, но я догадываюсь, что каждый разработчик рисует линию.
Что касается использования исключений, как следует из названия, их использование должно быть исключительным, поэтому для кода, представленного выше, вызов getGroup
должен возвращать null
, если служба не существует. Исключение должно происходить только в том случае, если сетевая ссылка не работает или что-то в этом роде.
Я предполагаю, что вывод состоит в том, что он немного отстает от команды разработчиков для каждого приложения, чтобы определить границы исключений assert vs.
Ответ 6
В соответствии с этим документом http://docs.oracle.com/javase/6/docs/technotes/guides/language/assert.html#design-faq-general, "Утверждающий оператор подходит для непубличного предусловия, постусловия и проверки инварианта класса. все еще выполняются проверками внутри методов, которые приводят к определенным, задокументированным исключениям, таким как IllegalArgumentException и IllegalStateException."
Если вы хотите узнать больше о предварительном условии, постусловии и инварианте класса, проверьте этот документ: http://docs.oracle.com/javase/6/docs/technotes/guides/language/assert.html#usage-conditions. Он также содержит примеры использования утверждений.
Ответ 7
Тестирование для null приведет к улову null, вызывающему проблемы, тогда как try/catch, поскольку у вас есть, будет ломать любую ошибку.
В целом, try/catch более безопасен, но немного медленнее, и вы должны быть осторожны, чтобы уловить все возможные ошибки. Поэтому я бы сказал, использовать try/catch - в один прекрасный день код getGroup может измениться, и вам может понадобиться эта большая сеть.
Ответ 8
Признаюсь, я немного смущен вашим вопросом. Когда условие утверждения не выполняется, генерируется исключение. Смутно это называется AssertionError. Обратите внимание, что он не установлен, например (IllegalArgumentException, который вызывается в очень похожих обстоятельствах.
Итак, используя утверждения в Java
- - более сжатый способ записи блока condition/throw
- позволяет вам включать/выключать эти проверки с помощью параметров JVM. Обычно я оставлял эти проверки все время, если они не влияют на производительность во время выполнения или имеют аналогичный штраф.
Ответ 9
Вы можете использовать эту простую разницу в виду при их использовании. Исключения будут использоваться для проверки ожидаемых и непредвиденных ошибок, которые называются проверенной и непроверенной ошибкой, в то время как утверждение используется в основном для целей отладки во время выполнения, чтобы проверить, подтверждены ли допущения или нет.
Ответ 10
См. раздел 6.1.2 (Утверждения против другого кода ошибки) документации Sun по следующей ссылке.
http://www.oracle.com/technetwork/articles/javase/javapch06.pdf
Этот документ дает лучший совет, который я видел, когда использовать утверждения. Цитирование из документа:
"Хорошее эмпирическое правило заключается в том, что вы должны использовать утверждение для исключительных случаев, о котором вы хотели бы забыть. Утверждение - это самый быстрый способ справиться с состоянием или состоянием, которое вы не ожидаете иметь, и забыть для решения".
Ответ 11
К сожалению, утверждения могут быть отключены. Когда в производстве вам нужна вся помощь, которую вы можете получить при отслеживании чего-то непредвиденного, так утверждает, что дисквалифицирует себя.