Почему нам не нужно добавлять try-catch в RuntimeException?
Я хочу спросить, почему нам не нужно добавлять блок try-catch в RuntimeException
, пока мы должны делать это с другими исключениями?
Я имею в виду:
public class Main {
public static void main(String[] args) {
throw new RuntimeException();
}
}
Изменить:
когда я говорю: throw new RuntimeException();
настолько ясно, что произойдет исключение, так почему компилятор не запрещает это?
Ответы
Ответ 1
Это потому, что это исключение unchecked. Его не нужно явно объявлять или вылавливать. Также см. учебник Sun по теме.
Обновление: в общем случае вы должны выбросить только RuntimeException
(желательно один из NullPointerException
) или незаконный аргумент (затем бросаем IllegalArgumentException
), или метод вызывается в неподходящий момент/состояние (затем бросает IllegalStateException
) и т.д. Вызывающий должен исправить свой код, чтобы избежать этого. Например. проверяя заранее, если аргумент не равен NULL, или если аргумент находится в правильном формате/синтаксисе, или убедитесь, что метод вызывается в нужный момент.
Если существует конкретная ситуация, которая должна вызывать исключение во время выполнения, и вы не можете использовать один из своих конкретных подклассов, тогда вы должны расширить его и правильно документировать в новом исключении javadoc и в вызывающем методе, например. ConfigurationException extends RuntimeException
для случая, когда вызывающий код не настроил приложение /API должным образом перед использованием. Это должно сигнализировать конечному пользователю (другому разработчику) достаточно для принятия соответствующих мер.
В двух словах: RuntimeExceptions
следует идентифицировать программно восстанавливаемые проблемы, вызванные ошибками в потоке или конфигурации кода (читай: ошибки разработчика). Проверено Exceptions
должно идентифицировать программно восстанавливаемые проблемы, вызванные неожиданными условиями вне контроля кода (например, сбой базы данных, ошибка ввода-вывода файла, неправильная вход конечного пользователя и т.д.). Errors
должен идентифицировать программно неустранимые проблемы (например, вне памяти, исключение внутри инициализатора и т.д.).
Ответ 2
RuntimeException
, Error
, и их подклассы специально не проверяются во время компиляции - они не являются частью формального контракта метода.
См. главу 11 в JLS, Исключения, в частности 11.2, Проверка времени исключения компиляции Исключения.
Ответ 3
Давайте спорить таким образом. Что делать, если NullPointerException было создано как исключение во время компиляции? Если бы это было сделано, компилятор должен был строго проверить, является ли переменная нулевой или нет. Это невозможно сделать.
public void dummyMethod(Object obj){
}
Здесь нет возможности для компилятора проверить, может ли obj быть нулевым или нет. Тем не менее, при возникновении сценария с нулевым указателем должна быть выбрана некоторая ошибка/исключение.
Ответ 4
В зависимости от языковой спецификации исключенные исключения не проверяются во время компиляции, что означает, что компилятор не требует методов для catch или для указания (с помощью throws
). Классы, относящиеся к этой категории, подробно описаны в разделе 11.2 Проверка исключений исключений в JLS:
Неконтролируемые классы исключений - это класс RuntimeException
и его подклассы, а класс Error
и его подклассы. Все остальные классы исключений - это проверенные классы исключений. API Java определяет ряд классов исключений, как проверенных, так и непроверенных. Дополнительные классы исключений, как проверенные, так и непроверенные, могут быть объявлены программистами. См. §11.5 для описания иерархии классов исключений и некоторых классов исключений, определенных Java API и виртуальной машиной Java.
Так как a RuntimeException
в неконтролируемом исключении, компилятор не заставляет вас обрабатывать его. Если вы хотите заставить вызывающего элемента кода обрабатывать исключение, используйте проверенное исключение (подклассы Exception
, отличные от RuntimeException
, все проверяемые классы исключений).
Ответ 5
Потому что не запрещено бросать исключения во время выполнения, и вам не нужно объявлять исключения во время выполнения. Ваша программа - действительная Java-программа, поэтому у компилятора нет причин жаловаться.
Ответ 6
В принципе, неперехваченное исключение является просто сокращением для отображения сообщения и завершения приложения.
Зачем вам это нужно? В некоторых случаях вы можете обнаружить, что что-то пошло не так, какой-то файл не загружается, api отсутствует, некоторые данные по какой-то причине повреждены или один из миллионов других вещей ошибочен. Если вы не генерируете исключение, приложение может просто сбой в другой точке или в худшем случае продолжать работать, пока ошибка возрастает, что затрудняет отладку.
Важно понимать, что выдается исключение, потому что есть ошибка, исключение - это не ошибка, это просто посланник.
Ответ 7
Большинство ответов на этом форуме говорили об иерархии Exception, и компилятор Java не поймал их, но я попытался бы ответить на это больше с точки зрения дизайна и почему, возможно, все было спроектировано так.
В основном, когда вы вызываете функцию (или записываете некоторый код), исключение может быть исключено из нее на основе трех разных ситуаций:
-
Исходя из неизбежного условия, такого как недоступность сети или ожидаемого файла, отсутствующего в файловой системе.
-
Основываясь на избегаемом, но известном условии, например Integer.parseInt(String)
, может бросать NumberFormatException
, если вызывающий объект передает неконвертируемую строку, например "Hello"
, но вызывающий может обеспечить правильную проверку на месте перед тем как перейти в любую строку к функции и полностью избавиться от возможности генерации исключения. Общим примером использования может быть проверка поля формы age
на веб-странице, прежде чем передавать его на более глубокие слои, которые делают преобразование.
-
Неизвестное или неожиданное условие В любой момент, когда какая-либо строка кода может вызывать исключение в вашем коде, потому что была некоторая ошибка, которую вы сделали, и не наблюдали условие ошибки, пока оно не взорвалось как правило, происходит с NullPointer Reference
, IndexOutOfBounds
и т.д., которое, если это наблюдается, возможно, относится к категории 2.
Исключения категории 1 обычно разрабатываются как Checked Exceptions
, потому что для этого необходимо обеспечить проверку на неизбежные условия ошибки и обеспечить их резервные копии. В примерах IOException проверяется исключение, поскольку в случае, если вы открываете файл, может быть много чего, что может пойти не так (например, файл может быть удален, разрешения и т.д.), И предварительная проверка всех из них может быть очень громоздкой.
Исключения 2-го типа обычно моделируются как Unchecked Exceptions
, потому что у вас может быть ваша предварительная проверка на месте, и может возникнуть раздражение, когда вы будете вынуждены использовать try и catch для ситуаций, о которых вы уже позаботились.
Исключения 3-го типа не нужно даже беспокоить вообще, потому что вы не можете поместить обработку ошибок в каждый код приложения, который может неожиданно возникнуть. Но иногда вы можете разместить глобальный обработчик, где-то совсем в стеке вызовов, из которого почти весь код приложения запускается и обрабатывает его в общем виде, чтобы ваше приложение не вылетало из-за непредвиденной ошибки.
Например, если вы используете веб-приложение, вы можете настроить свой контейнер сервлетов для отправки общей 500 Internal Server Error
для любой необработанной ошибки в вашем приложении. Или, если вы используете автономное приложение Java, вы можете сохранить содержимое своего main method
в блоке try catch
, чтобы предотвратить сбой приложения.