Исключение Vs Assertion

В чем разница между обработкой исключений Java и использованием условий assert?

Известно, что Assert имеет два типа. Но когда мы должны использовать ключевое слово assert?

Ответ 1

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

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

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

Ответ 2

Java-утверждения построены поверх исключений Java и обработки исключений. В самом деле, когда утверждение Java не выполняется, результатом является исключение AssertionError, которое можно поймать, как любое другое исключение Java. Ключевыми отличиями между исключениями и утверждениями являются:

  • Утверждения предназначены для использования исключительно в качестве средства обнаружения ошибок программирования, а также ошибок. Напротив, исключение может указывать на другие виды ошибок или "исключительных" условий; например неправильный ввод пользователя, отсутствие файлов, полная загрузка и т.д.
  • Язык Java обеспечивает синтаксическую поддержку утверждений в форме инструкции assert. Сравните следующее:

    if (x != y) {
         throw new SomeException("x != y");
    }
    
    assert x != y;
    
  • Самое главное, что Java позволяет включать или отключать проверку утверждений по всему миру или по отдельным классам при запуске JVM.

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

@Mario Ortegon прокомментировал так:

"Отключение" заключается в том, что утверждения могут использоваться для проверки результата оптимизированного алгоритма путем сравнения его реализации с известным, но медленным алгоритмом. Таким образом, в разработке нормально использовать этот метод O(N^3), чтобы утверждать, что алгоритм O(log N) работает по назначению. Но это то, чего вы не хотите в производстве.

Независимо от того, считаете ли вы хорошей практикой отключение утверждений в производстве, определенно плохая практика писать утверждения, которые оказывают значительное влияние на производительность при включении. Зачем? Потому что это означает, что у вас больше нет возможности разрешать утверждения в производстве (отслеживать проблему) или при тестировании напряжения/емкости. На мой взгляд, если вам нужно провести тестирование O(N^3) pre/post-condition, вы должны сделать это в своих модульных тестах.

Ответ 3

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

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

ссылка: http://geekexplains.blogspot.com/2008/06/asserions-in-java-assertions-vs.html

Ответ 4

Пример хорошего использования Assert:

assert flibbles.count() < 1000000; // too many flibbles indicate something is awry
log.warning("flibble count reached " + flibbles.count()); // log in production as early warning

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

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

ср. http://c2.com/cgi/wiki?FailFast см. также мою копию С# этого ответа: Debug.Assert vs. Specific Thrown Exceptions

Ответ 5

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

Используйте их, когда проблемы не должны быть исправлены, и на самом деле ДОЛЖНЫ НИКОГДА НЕ ПРОХОДИТЬСЯ В ПЕРВОМ МЕСТЕ. Сначала это звучит странно: не хотим ли мы защитить наш код от ВСЕХ потенциальных проблем? Обычно да. Но есть случай, когда мы этого не делаем. Этот случай называется "Дизайн по контракту".

Скажем, вы пишете заявку на банк. Как разработчик вы не можете поддерживать все возможные финансовые условия. Поэтому, прежде чем начинать код, вы получаете спецификацию из банка, которая дает вам допустимые диапазоны, которые это приложение должно поддерживать. Таким образом, ваша заявка разрабатывается по контракту (по спецификации из банка). В этом договоре будут определены основные принципы, которые всегда должны быть истинными, чтобы ваше приложение работало. Эти фундаментальные принципы называются "инвариантами" (потому что они не могут измениться). Дизайн по контракту упрощает вашу жизнь как разработчика - вы отвечаете только за поддержку объема работы, определенной в контракте.
Важно проверить значения этих инвариантов в вашем коде, но вы не должны проверять их, как если бы они были исключениями и пытались обойти их. Если они ошибаются - вы должны потерпеть неудачу, потому что входы не выполнили свои договорные обязательства.

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

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

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

Ответ 6

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

Исключение - это специальные системные события, которые всегда могут произойти: FileNotFound, ConnectionToServerLost и т.д.

Ответ 7

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