Исключения в Java: try, catch, finally
Обработка исключений в Java: блоки try, catch и finally, оператор throw, проверяемые и непроверяемые исключения, свои классы исключений.
Исключение — это объект, описывающий ошибку, возникшую во время выполнения. Если её не обработать, программа аварийно завершится. Механизм
try-catchпозволяет перехватить ошибку и продолжить работу.
try и catch
Опасный код помещают в блок try. Если внутри возникнет исключение, выполнение перейдёт в блок catch, где ошибку можно обработать.
public class Main {
public static void main(String[] args) {
try {
int result = 10 / 0; // ArithmeticException
System.out.println(result); // не выполнится
} catch (ArithmeticException e) {
System.out.println("Ошибка: деление на ноль");
}
System.out.println("Программа продолжает работу");
}
}
Вывод:
Ошибка: деление на ноль Программа продолжает работу
Без try-catch та же программа упала бы с сообщением ArithmeticException: / by zero и не дошла бы до последней строки.
Объект исключения
В блок catch попадает объект исключения. У него есть метод getMessage() с описанием ошибки.
int[] arr = {1, 2, 3};
try {
System.out.println(arr[5]); // выход за границу массива
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("Поймано: " + e.getMessage());
}
Вывод:
Поймано: Index 5 out of bounds for length 3
Блок finally
Блок finally выполняется всегда — и при ошибке, и без неё. В нём обычно освобождают ресурсы (закрывают файл, соединение).
try {
System.out.println("Открываем ресурс");
int x = 10 / 0;
} catch (ArithmeticException e) {
System.out.println("Поймали ошибку");
} finally {
System.out.println("Закрываем ресурс"); // выполнится в любом случае
}
Вывод:
Открываем ресурс Поймали ошибку Закрываем ресурс
Несколько catch
Для разных типов ошибок можно написать отдельные блоки catch — сработает первый подходящий.
try {
String s = null;
System.out.println(s.length()); // NullPointerException
} catch (ArithmeticException e) {
System.out.println("Арифметическая ошибка");
} catch (NullPointerException e) {
System.out.println("Обращение к null");
}
Вывод:
Обращение к null
Оператор throw
Исключение можно сгенерировать самому — оператором throw. Это полезно, чтобы сообщить о недопустимых данных.
static void setAge(int age) {
if (age < 0) {
throw new IllegalArgumentException("Возраст не может быть отрицательным");
}
System.out.println("Возраст: " + age);
}
// setAge(-5); → выбросит IllegalArgumentException
Проверяемые и непроверяемые
- Непроверяемые (
RuntimeExceptionи потомки:NullPointerException,ArithmeticException) — обычно следствие ошибок в коде. Компилятор их не требует обрабатывать. - Проверяемые (например,
IOException) — внешние ситуации. Компилятор требует либо обернуть их вtry-catch, либо объявить в сигнатуре черезthrows.
Своё исключение
Можно создать собственный тип, унаследовав Exception (или RuntimeException):
class InsufficientFundsException extends RuntimeException {
InsufficientFundsException(String message) {
super(message);
}
}
// throw new InsufficientFundsException("Недостаточно средств");
Коротко
- Опасный код — в
try, обработка ошибки — вcatch. finallyвыполняется всегда; в нём освобождают ресурсы.throwгенерирует исключение вручную.- Непроверяемые исключения компилятор не требует обрабатывать, проверяемые — требует.
- Свой тип ошибки создают наследованием от
Exception.