Необработанные исключения

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

class ЕхсО {
publicstatic void main(String args[]) {
int d = 0;
int a = 42 / d;
}
}

Когда система времени выполнения Java обнаруживает попытку деления на ноль, она конструирует новый объект исключения и затем возбуждает исключение. Это прерывает выполнение ЕхсО, поскольку как только исключение возбуждено, оно должно быть перехвачено обработчиком исключений, а тот должен немедленно с ним что-то сделать. В данном примере мы не применили никакого собственного обработчика исключений, поэтому исключение перехватывается обработчиком по умолчанию, предоставленным системой времени выполнения Java. Любое исключение, которое не перехвачено вашей программой, в конечном итоге будет перехвачено и обработано этим обработчиком по умолчанию. Обработчик по умолчанию отображает строку, описывающую исключение, печатает трассировку стека от точки возникновения исключения и прерывает программу. Ниже приведен пример исключения, сгенерированного представленным выше кодом:

java.lang.ArithmeticException:
by zero at ExcO.main(ExcO.java:4)

Обратите внимание, что имя класса ExcO, имя метода main, имя файла ExcO. java и номер строки 4 включены в трассировку стека. Также нужно обратить внимание на то, что возбужденное исключение является подклассом Exception, называемым ArithmeticException, который более точно описывает тип возникшей ошибки. Как будет показано далее в настоящей главе, Java применяет несколько встроенных типов исключений, соответствующих разным типам ошибок времени выполнения, которые могут быть сгенерированы.

Трассировка стека всегда покажет последовательность вызовов методов, которая привела к ошибке. Например, вот другая версия предыдущей программы, представляющая ту же ошибку, но в методе, отдельном от main ():

class Excl {
static void subroutine () {
int d = 0;
int a = 10 / d;
}
public static void main(String args[]) {
Excl.subroutine ();
}
}

Результирующая трассировка стека обработчика исключений по умолчанию показывает весь стек вызовов:

java.lang.ArithmeticException:
by zero at Excl.subroutine(Excl.java:4)
at Excl.main(Excl.java:7)

Как видите, в нижней части стека находится строка 7 метода main, в которой расположен вызов subroutine (), породивший исключение в строке 4. Трассировка стека достаточно удобна для отладки, поскольку показывает всю последовательность вызовов, приведших к ошибке.