Должны ли непроверенные исключения быть обнаружены и обработаны?
В последнее время я читал много сообщений об исключениях, и у меня возник вопрос, нужно ли перехватывать непроверенные исключения. Я прочитал, что если вы хотите, чтобы ваше приложение восстанавливалось после ошибки, вы используете проверенные исключения. Однако, если вы не можете обработать проверенное исключение, вы либо заключаете его в другое проверенное исключение, чтобы вы могли передать его другому слою; например, вы заверните SqlException
или вы выбрасываете непроверенное исключение. Тем не менее, вы должны ловить непроверенные исключения? Являются ли непроверенные исключения идеальными ошибками программирования, которые вы не проверяете? Должны ли они просто всплыть из вашего приложения?
6 ответов
Должны ли непроверенные исключения быть обнаружены и обработаны?
Ответ таков:
Это зависит от того, что является исключением.
Это зависит от того, почему было сгенерировано исключение. Было ли это "ожидаемым"? Это было из-за ошибки, плохого ввода или экологической проблемы? Или что-то другое?
Это зависит от того, есть ли хороший способ выздоровления. Это обычно зависит отчасти от предыдущих критериев.
Если исключение является неожиданным, причина исключения является неопределенной, и / или если не существует надежной стратегии восстановления, если вы все же поймаете исключение, то обычно лучше разрешить возникновение исключения и убедиться, что оно получено. сообщили / вошли на верхнем уровне.
И если исключением является Error
, общее правило таково, что вы НЕ должны пытаться восстановиться. И это включает в себя StackruError
и (особенно) OutOfMemoryError
, Error
исключения указывают на проблему, которую трудно (или невозможно) безопасно устранить, и лучшая стратегия состоит в том, чтобы разрешить или заставить приложение завершиться.
Что вы имеете в виду, когда сообщили / вошли на верхнем уровне? Например, вы хотите поймать его на уровне пользовательского интерфейса и показать диалог, войти в него и т. Д.?
Я имею в виду, что исключение и его трассировка стека должны быть записаны в файл журнала приложения, чтобы сопровождающие могли видеть свидетельства проблемы. Пытаетесь ли вы объяснить проблему конечному пользователю (и как вы это делаете) - это отдельная проблема.
"Верхний уровень" может быть методом "main", методом "run" потока или runnable или обработчиком необработанных исключений. По сути, это то место, где исключение в конечном итоге будет "всплывать", если оно не будет обнаружено.
Вы должны поймать исключение - проверено или не проверено - если вы можете справиться с ним осмысленно, чтобы устранить проблему. Как правило, вы не должны ловить исключение, если у вас нет хорошего способа его обработать.
Я видел слишком много кода, который "обрабатывает" исключения, делая e.printStackTrace()
и затем продолжаю, как будто ничего не случилось. Игнорирование такой проблемы обычно приводит к другим проблемам позже.
Ничто не запрещает вам ловить исключения во время выполнения.
В настоящее время тенденция состоит в том, чтобы использовать все больше и больше исключений времени выполнения и все меньше и меньше проверенных исключений. Spring, Hibernate и последние спецификации Java EE используют исключения времени выполнения почти исключительно. Это делает бизнес-код более легким для чтения и менее громоздким.
Исключения времени выполнения, как правило, предназначены для того, чтобы вообще не перехватываться или только перехватываться в нижней части стека вызовов на уровне пользовательского интерфейса для отображения сообщения об ошибке, поскольку обычно это единственное, что вы можете сделать, когда такое исключение происходит.
Выбор для проверенных исключений обычно: вы просто добавляете его в throws
если вы не можете ничего с этим поделать, catch
и преобразовать его в новое исключение с исходным в качестве причины, если вы не можете ничего с этим поделать, но можете добавить информацию, и catch
это и делать что-то с этим, если это возможно, а также правильное место в вашем коде, чтобы сделать что-то с этим.
Непроверенные исключения немного сложнее. В идеальном мире они должны указывать на ошибки программирования / логики и обрабатываться почти так же, как и ошибки утверждения, не обнаруженные и особенно не проглоченные.
По моему мнению, некоторые непроверенные исключения, поступающие из стандартной библиотеки Java или других библиотек, должны действительно проверяться, но это не так. Это случаи, когда вызывающий должен признать, что такие исключения могут проходить через них, даже если они этого не делают. catch
их. Для неконтролируемых исключений, которые также могут быть проверены, в основном одни и те же правила: ловите их, если хотите что-то с ними сделать, в противном случае дайте им всплыть. Если вы создаете библиотеку (даже если она только внутренняя для приложения), и непроверенное исключение действительно является чем-то, что должно быть перехвачено позже, тогда вы можете захотеть отловить и повторно выбросить ее, завернутую в проверенное исключение в коде библиотеки.,
В общем, старайтесь избегать создания исключений. Проверьте ввод, так что вам не нужно catch
, и если исключение все еще выброшено, то это ошибка, и ее следует оставить необработанной. Только catch
их, если это единственный или, по крайней мере, явно лучший способ.
Чтобы быть справедливым по отношению к библиотекам Java, язык был разработан в эпоху, когда IDE еще не сразу жаловались на пропущенные предложения throws и предлагали заполнять их автоматически, поэтому их снятие с контроля могло быть оправдано снижением нагрузки на разработчика. Но с современными инструментами нет оправдания.
И затем, как упоминалось в других ответах, есть непроверенные исключения, которые вы не должны ловить.
Основная разница между Checked
а также Unchecked
Исключением является то, что вам нужно явно обрабатывать первое или распространять его в inheritance hierarchy
Пока это не требуется для последующих.
Также, CheckedException
простираться от java.lang.Exception
, в то время как UncheckedExceptions
простираться от java.lang.RuntimeException
, которые не должны быть обработаны. Обратите внимание, что, RuntimeException
сами являются подклассом Exception
,
Учитывая, вся информация выше, если вы handle
unchecked exception
тогда это хорошо. Он будет работать нормально, и управление перейдет к соответствующему catch
блок. Но ты не должен этого делать. Если вам это действительно не нужно, и у вас есть правильный способ справиться с ними.
Например: - Вы должны обращаться с
IllegalArgumentException
который являетсяUnchecked Exception
,И потом, вы не должны обрабатывать ошибки, такие как: -
StackruError
, Как, вы не знаете, почему эта проблема могла возникнуть, и что может быть подходящим способом для ее решения. Так что, просто оставьте это JVM.Errors
являютсяUnchecked Exception
что вы не можете оправиться от.
Для более подробной информации, обратитесь к этим ссылкам: -
вы должны ловить непроверенные исключения?
Да и Нет. Зависит от того, какое исключение выдается.
Являются ли непроверенные исключения идеальными ошибками программирования, которые вы не проверяете?
Вы можете написать catch
блок, чтобы поймать непроверенное исключение, но опять-таки зависит, следует ли вам. Если вы это сделаете, то возможно, что ошибка остается нерешенной в течение длительного времени, и к тому времени, когда она обнаружена, ее размер также изменяется.
Должны ли они просто всплыть из вашего приложения?
Если они происходят, попытайтесь решить их причину (если это возможно). не catch
их всегда так же сложно и быстро.