Обработка исключений в Java
В Java исключения обрабатываются с помощью конструкции try-catch-finally, где finally – опциональная ветка, при наличии выполняется как после try, так и любой из веток catch. Кроме того, часто исключения не перехватываются в том методе, где возникают, а пробрасываются выше по стеку вызовов. В этом случае метод в своем заголовке должен содержать throws класс_исключения
. Если может быть выброшено несколько исключений, они перечисляются через запятую.
Обработка на месте:
import java.io.*; public class ExTest { public static void main(String[] args) { try { FileInputStream file = new FileInputStream( "test.txt"); System.out.println("File ready"); } catch (FileNotFoundException e) { System.out.println("Input problem"); System.out.println(e); } } }
Проброс:
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; public class ExTest2 { public static void main(String[] args) throws IOException { String s = getString(); } public static String getString() throws IOException { BufferedReader reader = new BufferedReader( new InputStreamReader( System.in)); return reader.readLine(); } }
Во втором примере исключение можно было бы обработать в try-catch в методе main(). Можно указывать родительский класс исключения. Так вместо FileNotFoundException допустимо писать IOExctption или вообще класс Exception.
В Java исключения делятся на контролируемые (проверяемые) компилятором и неконтролируемые (непроверяемые). Приведенный выше исключения, которые могут возникать при вводе данных, – пример контролируемых. Если их не обработать или не передать вызывающему методу, то программу нельзя будет скомплировать.
Непроверяемые компилятором исключения должен контролировать сам программист. Так приведенная ниже программа удачно скомпилируется. Ошибка обнаружится лишь в процессе ее выполнения (runtime), если значение a окажется равным нулю.
import java.util.Scanner; public class ExTest3 { public static void main(String[] args) { Scanner scan = new Scanner(System.in); int a = scan.nextInt(); System.out.println(10/a); } }
Обработать исключение можно так:
import java.util.Scanner; public class ExTest3 { public static void main(String[] args) { Scanner scan = new Scanner(System.in); int a = scan.nextInt(); try { System.out.println(10 / a); } catch (ArithmeticException e) { System.out.println("0 is bad divisor"); } finally { System.out.println("End of the program"); } } }
Классов исключений в Java несколько сотен. По большей части они связаны между собой наследственными связями. Исходным является дочерний от Object класс Throwable. У него есть два наследника: Error и собственно Exception.
Объекты, порожденные от наследников Error, возникают в момент выполнения программы и связаны с работой java-машины. Примером подобной ошибки является недостаток памяти. Такие ошибки в коде не обрабатывают. Они скорее свидетельствует, что код сам по себе плох, его надо переписывать. Все Error'ы относятся к непроверяемым на этапе компиляции.
Непосредственно от класса Exсeption происходят классы RuntimeException и IOException. Первая группа относится к непроверяемым, вторая – к проверяемым.