В большинстве ответов на этом форуме говорилось об иерархии исключений и о том, что компилятор Java их не улавливает, но я постараюсь ответить на этот вопрос подробнее с точки зрения дизайна и почему, возможно, все было спроектировано так.
Обычно, когда вы вызываете функцию (или пишете некоторый код), из нее может быть выдано исключение, основанное на трех различных ситуациях:
На основании неизбежного условия , например недоступности сети или отсутствия ожидаемого файла в файловой системе.
На основе предотвратимого, но известного условия , например, Integer.parseInt(String)
может выдать NumberFormatException
, если вызывающий передает необратимую строку, такую как "Hello"
, но вызывающий может обеспечить надлежащую проверку на месте до передать любую строку в функцию и полностью покончить с возможностью генерации исключения. Распространенным вариантом использования может быть проверка поля формы age
на веб-странице перед передачей его на более глубокие слои, которые выполняют преобразование.
Неизвестное или неожиданное условие Каждый раз, когда какая-то строка кода может вызвать исключение в вашем коде, потому что произошла какая-то ошибка, которую вы сделали и не наблюдали условие ошибки, пока оно не сработало в производстве, как правило, происходит с NullPointer Reference
, IndexOutOfBounds
и т. д., которые при наблюдении могут попасть в категорию 2.
Исключения для категории 1 обычно обозначаются как Checked Exceptions
, поскольку для этого необходимо обеспечить проверку на наличие неизбежных ошибок и обеспечить их откат. Для примеров IOException - проверенное исключение, потому что в случае, если вы открываете файл, может быть много вещей, которые могут пойти не так (например, файл может быть удален, права доступа и т. Д.), И предварительная проверка всех из них может быть очень громоздкой.
Исключения 2-го типа обычно смоделированы как Unchecked Exceptions
, потому что у вас может быть предварительная проверка на месте, и это может раздражать, когда вы вынуждены использовать попытку и ловить для ситуаций, о которых вы уже позаботились.
Об исключениях 3-го типа вообще не нужно беспокоиться, потому что вы не можете поместить обработку ошибок в каждый оператор кода приложения, который может неожиданно появиться. Но иногда вы можете разместить глобальный обработчик, где-то достаточно высоко в стеке вызовов, из которого выполняется почти весь код приложения, и обрабатывать его обобщенным образом, чтобы ваше приложение не зависало из-за непредвиденной ошибки.
Например, если вы запускаете веб-приложение, вы можете настроить контейнер сервлетов на отправку общего 500 Internal Server Error
для любой необработанной ошибки в вашем приложении. Или, если вы работаете в автономном приложении Java, вы можете сохранить содержимое вашего main method
в блоке try catch
, чтобы предотвратить сбой приложения.