Если мы создадим исключение в методе main и не обработаем его, оно будет работать нормально. Фактически

public static void main(String[] args) throws IOException {
    throw new IOException(); //OK
}

Но Java требует, чтобы любое проверенное исключение обрабатывалось в программе, поэтому следует обрабатывать IOException. Кто на самом деле обрабатывает IOException в этом случае?

Обратите внимание, что спецификация языка Java определяет, что исключение обрабатывается, если оно заключено в блок try, содержащий предложение catch, тип которого является супертипом исключения.

5
user3663882 22 Фев 2015 в 11:34

3 ответа

Лучший ответ

Если вы не предприняли никаких специальных действий, чтобы самостоятельно поймать исключение, выполняется ThreadGroup по умолчанию uncaughtException.

Это указано в главе 11.3 JLS .

Если не удается найти предложение catch, которое может обрабатывать исключение, текущий поток (поток, обнаруживший исключение) завершается. Перед завершением все предложения finally выполняются, а неперехваченное исключение обрабатывается в соответствии со следующими правилами:

  1. Если текущий поток имеет установленный обработчик неперехваченных исключений, то этот обработчик выполняется.

  2. В противном случае метод uncaughtException вызывается для ThreadGroup, который является родителем текущего потока. Если ThreadGroup и его родительский ThreadGroups не переопределяют uncaughtException, тогда вызывается метод обработчика по умолчанию uncaughtException.

Кроме того, javadoc ThreadGroup.uncaughtException читается следующим образом:

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

Метод uncaughtException объекта ThreadGroup выполняет следующие действия:

  • Если эта группа потоков имеет родительскую группу потоков, метод uncaughtException этого родительского потока вызывается с теми же двумя аргументами.
  • В противном случае этот метод проверяет, установлен ли обработчик неперехваченных исключений по умолчанию, и если да, то его метод uncaughtException вызывается с теми же двумя аргументами.
  • В противном случае этот метод определяет, является ли аргумент Throwable экземпляром ThreadDeath. Если да, то ничего особенного не делается. В противном случае сообщение, содержащее имя потока, возвращенное из метода потока getName, и трассировку стека, используя метод printStackTrace Throwable, печатается в стандартный поток ошибок.
9
Community 20 Июн 2020 в 09:12

Сама JVM обрабатывает исключения, генерируемые из main().

1
AlexR 22 Фев 2015 в 08:36

Если исключение не перехвачено, вызывается обработчик неперехваченных исключений потока или группы потоков, а затем поток завершается.

В главе 11 JLS говорится который:

Если не найдено ни одного предложения catch, которое может обрабатывать исключение, то текущий поток (поток, обнаруживший исключение) прекращено. Перед прекращением действия все условия finally выполняются и неперехваченное исключение обрабатывается в соответствии со следующими правилами:

Если текущий поток имеет установленный обработчик неперехваченных исключений, то этот обработчик выполняется.

В противном случае метод uncaughtException вызывается для ThreadGroup, который является родителем текущего потока. Если ThreadGroup и его родительские ThreadGroup не отменяют uncaughtException, затем метод обработчика по умолчанию uncaughtException вызывается.

2
RealSkeptic 22 Фев 2015 в 08:46