Почему нам не нужно добавлять try-catch в RuntimeException? - PullRequest
19 голосов
/ 01 мая 2010

Я хочу спросить, почему нам не нужно добавлять блок try-catch к RuntimeException, в то время как мы должны делать это с другими исключениями?

Я имею в виду, как:

public class Main {
    public static void main(String[] args) {
       throw new RuntimeException();
    }
}

Редактировать: когда я говорю: throw new RuntimeException(); так ясно, что произойдет исключение, так почему компилятор не запрещает это?

Ответы [ 7 ]

30 голосов
/ 01 мая 2010

Это потому, что это исключение не проверено . Это не должно быть явно объявлено или перехвачено. Также см. Учебник Sun по теме .

Обновление: в общем, вы должны только выбросить RuntimeException (предпочтительно один из его подклассов , перечисленных в javadoc), чтобы сигнализировать, что вызывающая сторона делает это неправильно. То есть передача аргумента null (затем выбросить NullPointerException) или недопустимый аргумент (затем выбросить IllegalArgumentException), либо метод вызывается в неправильный момент / состояние ( затем бросьте IllegalStateException) и так далее. Вызывающий должен исправить свой код, чтобы избежать этого. Например. предварительно проверять, является ли аргумент не нулевым, или аргумент имеет правильный формат / синтаксис, или гарантировать, что метод вызывается в нужный момент.

Если есть конкретная ситуация, которая должна вызвать исключение времени выполнения, и вы не можете использовать один из его определенных подклассов, то вы должны расширить его и правильно задокументировать его в javadoc нового исключения и в вызывающем методе, например, ConfigurationException extends RuntimeException для случая, когда вызывающий код не настроил приложение / API должным образом перед использованием. Это должно быть достаточным сигналом для конечного пользователя (другого разработчика), чтобы он предпринял соответствующие действия.

В двух словах: RuntimeExceptions должны идентифицировать программно исправимые проблемы, которые вызваны ошибками в потоке кода или конфигурации (читай: ошибки разработчика). Установленный флажок Exceptions должен идентифицировать программно исправимые проблемы, которые вызваны непредвиденными условиями вне контроля кода (например, сбой базы данных, ошибка ввода-вывода файла, неправильный ввод данных пользователем и т. Д.). Errors должен идентифицировать программно неисправимые проблемы (например, нехватка памяти, исключение внутри инициализатора и т. Д.).

3 голосов
/ 01 мая 2010

Давайте поспорим так. Что, если NullPointerException был разработан как исключение времени компиляции? Если бы это было сделано, компилятор должен был строго проверить, является ли переменная нулевой или нет. Это никак не может быть сделано.

public void dummyMethod(Object obj){

}

Здесь для компилятора нет способа проверить, может ли объект быть нулевым или нет. Однако при возникновении сценария с нулевым указателем должна быть какая-то ошибка / исключение.

2 голосов
/ 01 мая 2010

Согласно спецификации языка, непроверенные исключения не проверяются во время компиляции , что означает, что компилятору не требуются методы для их перехвата или указания (с throws) , Классы, принадлежащие к этой категории, подробно описаны в разделе 11.2 Проверка исключений во время компиляции JLS:

Классы непроверенных исключений - это класс RuntimeException и его подклассы, а также класс Error и его подклассы . Все остальные классы исключений проверенные классы исключений . Java API определяет несколько классов исключений, как проверенных, так и непроверенных. Дополнительные классы исключений, как проверенные, так и непроверенные, могут быть объявлены программистами. См. §11.5 для описания иерархии классов исключений и некоторых классов исключений, определенных Java API и виртуальной машиной Java.

Итак, поскольку RuntimeException в непроверенном исключении, компилятор не заставляет вас обрабатывать его. Если вы хотите, чтобы вызывающий фрагмент кода обрабатывал исключение, используйте проверенное исключение (подклассы Exception, отличные от RuntimeException, - все проверенные классы исключений).

2 голосов
/ 01 мая 2010

RuntimeException, Error и их подклассы специально не проверяются во время компиляции - они не являются частью формального контракта метода.

См. Главу 11 в JLS, Исключения, в частности 11.2, Проверка исключений во время компиляции.

1 голос
/ 17 ноября 2015

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

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

  1. На основании неизбежного условия , например недоступности сети или отсутствия ожидаемого файла в файловой системе.

  2. На основе предотвратимого, но известного условия , например, Integer.parseInt(String) может выдать NumberFormatException, если вызывающий передает необратимую строку, такую ​​как "Hello", но вызывающий может обеспечить надлежащую проверку на месте до передать любую строку в функцию и полностью покончить с возможностью генерации исключения. Распространенным вариантом использования может быть проверка поля формы age на веб-странице перед передачей его на более глубокие слои, которые выполняют преобразование.

  3. Неизвестное или неожиданное условие Каждый раз, когда какая-то строка кода может вызвать исключение в вашем коде, потому что произошла какая-то ошибка, которую вы сделали и не наблюдали условие ошибки, пока оно не сработало в производстве, как правило, происходит с NullPointer Reference, IndexOutOfBounds и т. д., которые при наблюдении могут попасть в категорию 2.

Исключения для категории 1 обычно обозначаются как Checked Exceptions, поскольку для этого необходимо обеспечить проверку на наличие неизбежных ошибок и обеспечить их откат. Для примеров IOException - проверенное исключение, потому что в случае, если вы открываете файл, может быть много вещей, которые могут пойти не так (например, файл может быть удален, права доступа и т. Д.), И предварительная проверка всех из них может быть очень громоздкой.

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

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

Например, если вы запускаете веб-приложение, вы можете настроить контейнер сервлетов на отправку общего 500 Internal Server Error для любой необработанной ошибки в вашем приложении. Или, если вы работаете в автономном приложении Java, вы можете сохранить содержимое вашего main method в блоке try catch, чтобы предотвратить сбой приложения.

1 голос
/ 01 мая 2010

По сути, необработанное исключение - это просто сокращение для отображения сообщения и завершения приложения.

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

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

1 голос
/ 01 мая 2010

Поскольку не исключено создание исключений времени выполнения, и вам не нужно объявлять исключения времени выполнения. Ваша программа является допустимой Java-программой, поэтому у компилятора нет причин жаловаться.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...