Исключения в Java: грамотная обработка ошибок
Исключение (exception) — проблема, возникающая во время выполнения программы, прерывающая нормальный поток. Необработанные исключения приводят к аварийному завершению, поэтому их нужно перехватывать и обрабатывать.
Три категории исключений
- Проверяемые (Checked exceptions) — проверяются компилятором (compile-time). Нельзя игнорировать, обязательно обработать (try-catch или throws). Пример:
FileNotFoundException,IOException. - Непроверяемые (Unchecked exceptions / Runtime Exceptions) — возникают во время выполнения. Ошибки программирования: логические ошибки, неправильное использование API. Компилятор их не проверяет. Пример:
NullPointerException,ArrayIndexOutOfBoundsException. - Ошибки (Errors) — серьезные проблемы, выходящие за контроль программы (например,
OutOfMemoryError,StackOverflowError). Обычно не обрабатываются.
Пример проверяемого исключения
import java.io.File;
import java.io.FileReader;
public class FilenotFound_Demo {
public static void main(String args[]) {
File file = new File("E://file.txt");
FileReader fr = new FileReader(file); // компилятор требует обработки FileNotFoundException
}
}
Пример непроверяемого исключения
public class Unchecked_Demo {
public static void main(String args[]) {
int num[] = {1, 2, 3, 4};
System.out.println(num[5]); // ArrayIndexOutOfBoundsException
}
}
Иерархия исключений
Все исключения наследуются от java.lang.Exception, который наследуется от Throwable. От Throwable также наследуется Error. Основные подклассы Exception: IOException и RuntimeException.
Основные методы Throwable
| Метод | Описание |
|---|---|
getMessage() | Подробное сообщение об ошибке |
getCause() | Причина исключения (объект Throwable) |
toString() | Имя класса + сообщение |
printStackTrace() | Вывод трассировки стека в System.err |
getStackTrace() | Массив элементов стека |
fillInStackTrace() | Заполнение трассировки текущим стеком |
Перехват исключений: try-catch
try {
// защищённый код
} catch (ExceptionType e) {
// обработка
}
Блок try должен следовать за catch или finally. Можно несколько catch-блоков подряд.
Пример
public class ExcepTest {
public static void main(String args[]) {
try {
int a[] = new int[2];
System.out.println("Access element three: " + a[3]);
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("Exception thrown: " + e);
}
System.out.println("Out of the block");
}
}
Результат:
Exception thrown: java.lang.ArrayIndexOutOfBoundsException: 3
Out of the block
Множественные catch-блоки
Исключение проверяется по порядку catch-блоков. Первым подходит наиболее конкретный тип.
Мульти-catch (Java 7+)
Один catch для нескольких типов:
catch (IOException | FileNotFoundException ex) {
logger.log(ex);
throw ex;
}
Ключевые слова throws и throw
throws— в сигнатуре метода, указывает, что метод может выбросить проверяемое исключение (откладывает обработку).throw— явное выброс исключения:throw new RemoteException();
public void withdraw(double amount) throws RemoteException, InsufficientFundsException {
// реализация
}
Блок finally
Выполняется всегда, независимо от исключения. Используется для очистки (закрытие ресурсов).
try {
// код
} catch (Exception e) {
// обработка
} finally {
// очистка
}
Пример
public class ExcepTest {
public static void main(String args[]) {
int a[] = new int[2];
try {
System.out.println("Access element three: " + a[3]);
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("Exception thrown: " + e);
} finally {
a[0] = 6;
System.out.println("First element value: " + a[0]);
System.out.println("The finally statement is executed");
}
}
}
Try-with-resources (Java 7+)
Автоматическое управление ресурсами (AutoCloseable). Ресурсы закрываются автоматически в обратном порядке.
try (FileReader fr = new FileReader("file.txt")) {
char[] a = new char[50];
fr.read(a);
for (char c : a) System.out.print(c);
} catch (IOException e) {
e.printStackTrace();
}
Требования: класс должен реализовывать AutoCloseable.
Пользовательские исключения
Создаются путём наследования от Exception (checked) или RuntimeException (unchecked).
public class InsufficientFundsException extends Exception {
private double amount;
public InsufficientFundsException(double amount) { this.amount = amount; }
public double getAmount() { return amount; }
}
Пример использования
public class CheckingAccount {
private double balance;
public void withdraw(double amount) throws InsufficientFundsException {
if (amount <= balance) balance -= amount;
else throw new InsufficientFundsException(amount - balance);
}
}
Распространённые исключения
- JVM Exceptions:
NullPointerException,ArrayIndexOutOfBoundsException,ClassCastException. - Programmatic Exceptions:
IllegalArgumentException,IllegalStateException.
java
- Освоение операторов Java: типы, синтаксис и практические примеры
- Комментарии в Java: типы, использование и лучшие практики
- Освоение улучшенного цикла for в Java: синтаксис, примеры и лучшие практики
- Освоение строк в Java: создание, методы и лучшие практики
- Обработка исключений в Java: try, catch, finally, throw и throws
- Java throw vs throws: мастерство обработки исключений с практическими примерами
- Мульти-исключения в Java: перехват нескольких исключений в одном catch блоке
- Try-with-resources в Java: автоматическое управление ресурсами
- Аннотации в Java: типы, размещение и практические примеры
- Assertions в Java: практическое руководство по обнаружению багов и обеспечению надежности кода