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

StackOverflow https://stackoverflow.com/questions/1957645

  •  21-09-2019
  •  | 
  •  

Вопрос

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

Например,

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
}

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

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

Это было полезно?

Решение

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

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

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

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

Другие советы

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

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

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

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

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

Также вам следует прочитать Статья Oracle о assert чтобы увидеть больше случаев, когда использовать - или не использовать - 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 подходит для проверки непубличных предварительных условий, постусловий и инвариантов к классу.Проверка общедоступных предварительных условий по-прежнему должна выполняться с помощью проверок внутри методов, которые приводят, в частности, к документированным исключениям, таким как IllegalArgumentException и IllegalStateException ".

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

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

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

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

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

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

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

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

Итак, используя утверждения в Java

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

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

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

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top