Исключение в Java - это обьект, который описывает исключителъное состояние, возникшее в каком-либо участке программного кода.
К механизму обработки исключений в Java имеют отношение 5 ключевых слов: — try, catch, throw, throws и finally.Схема работы этого механизма следующая. Вы пытаетесь (try) выполнить блок кода, и если при этом возникает ошибка, система возбуждает (throw) исключение, которое в зависимости от его типа вы можете перехватить (catch) или передать умалчиваемому (finally) обработчику.
try{ // блок кода } catch (ТипИсключения1 е){ // обработчик исключений типа ТипИсключения1 } catch (ТипИсключения2 е){ // обработчик исключений типа ТипИсключения2 throw(e) // повторное возбуждение исключения } finally { }
Для задания блока программного кода, который требуется защитить от исключений, исполь-зуется ключевое слово try. Сразу же после try-блока помещается блок catch, задающий тип исключения которое вы хотите обрабатывать.
public static void main(String[] args) { try { int d = 0; int a = 42 / d; } catch (ArithmeticException e) { System.out.println("Делить на ноль нельзя"); } }
Целью большинства хорошо сконструированных catch-разделов долж-на быть обработка возникшей исключительной ситуации и приведение переменных программы в некоторое разумное состояние - такое, чтобы программу можно было продолжить так, будто никакой ошибки и не было
try { int a = 10; int b = 42 / a; int c[] = { 1 }; c[42] = 99; } catch (ArithmeticException e) { System.out.println("Исключение:"+e); } catch(ArrayIndexOutOfBoundsException e) { System.out.println("array index oob: " + e); }
Вложенные операторы try
static void procedure() { try { int c[] = { 1 }; c[42] = 99; } catch(ArrayIndexOutOfBoundsException e) { System.out.println("array index oob: " + e); } } public static void main(String args[]) { try { int a = 0; System.out.println("a = " + a); int b = 42 / a; procedure(); } catch (ArithmeticException e) { System.out.println("div by 0: " + e); } }
Оператор throw используется для возбуждения исключения . Для того, чтобы сделать это, нужно иметь объект подкласса клас-са Throwable, который можно либо получить как параметр оператора catch, либо создать с помощью оператора new.
static void demoproc() { try { throw new NullPointerException("demo"); } catch (NullPointerException e) { System.out.println("Поймано исключение demoproc"); throw e; } } public static void main(String args[]) { try { demoproc(); } catch(NullPointerException e) { System.out.println("recaught: " + e); } }
В этом примере обработка исключения проводится в два приема. Метод main создает контекст для исключения и вызывает demoproc. Метод demoproc также устанавливает контекст для обработки исключе-ния, создает новый объект класса NullPointerException и с помощью опе-ратора throw возбуждает это исключение. Исключение перехватывается в следующей строке внутри метода demoproc, причем объект-исключение доступен коду обработчика через параметр e. Код обработчика выводит сообщение о том, что возбуждено исключение, а затем снова возбуждает его с помощью оператора throw, в результате чего оно передается обра-ботчику исключений в методе main.
Если метод способен возбуждать исключения, которые он сам не об-рабатывает, он должен объявить о таком поведении, чтобы вызывающие методы могли защитить себя от этих исключений.
static void procedure() throws IllegalAccessException { System.out.println(" inside procedure"); throw new IllegalAccessException("demo"); } public static void main(String args[]) { try { procedure(); } catch (IllegalAccessException e) { System.out.println("caught " + e); } }
Иногда требуется гарантировать, что определенный участок кода будет выпол-няться независимо от того, какие исключения были возбуждены и пере-хвачены. Для создания такого участка кода используется ключевое слово finally. Даже в тех случаях, когда в методе нет соответствующего воз-бужденному исключению раздела catch, блок finally будет выполнен до того, как управление перейдет к операторам, следующим за разделом try. У каждого раздела try должен быть по крайней мере или один раз-дел catch или блок finally. Блок finally очень удобен для закрытия файлов и освобождения любых других ресурсов, захваченных для временного использования в начале выполнения метода. Ниже приведен пример класса с двумя методами, завершение которых происходит по разным причинам, но в обоих перед выходом выполняется код раздела finally.
static void procA() { try { System.out.println("inside procA"); throw new RuntimeException("demo"); } finally { System.out.println("procA's finally"); } } static void procB() { try { System.out.println("inside procB"); return; } finally { System.out.println("procB's finally"); } } public static void main(String args[]) { try { procA(); } catch (Exception e) { System.out.println(e); } procB(); }
Только подклассы класса Throwable могут быть возбуждены или пере-хвачены. Простые типы - int, char и т.п., а также классы, не являю-щиеся подклассами Throwable, например, String и Object, использоваться в качестве исключений не могут. Наиболее общий путь для использова-ния исключений - создание своих собственных подклассов класса Ex-ception.
class MyException extends Exception { private int detail; MyException(int a) { detail = a; } public String Exc() { return "MyException["+detail+"]"; } } public class Main { public static void main(String args[]) { try { compute(1); compute(20); } catch (MyException e) { System.out.println("caught" + e); } } static void compute(int a) throws MyException { System.out.println("called computer+a+"); if (a > 10) throw new MyException(a); System.out.println("normal exit."); } }
Этот пример довольно сложен. В нем сделано объявление подкласса MyException класса Exception. У этого подкласса есть специальный кон-структор, который записывает в переменную объекта целочисленное значение, и совмещенный метод Exc, выводящий значение, хранящееся в объекте-исключении.