Исключения (Exceptions)

Быстрая навигация


Иерархия

Throwable
├── Error           — серьёзные сбои JVM, не ловим
│   ├── OutOfMemoryError
│   └── StackOverflowError
└── Exception
    ├── RuntimeException  — Unchecked, можно не обрабатывать
    │   ├── NullPointerException
    │   ├── ArrayIndexOutOfBoundsException
    │   ├── ClassCastException
    │   ├── ArithmeticException
    │   └── IllegalArgumentException
    └── IOException       — Checked, ОБЯЗАН обработать
        ├── FileNotFoundException
        └── ...

try / catch / finally

try {
    // код, который может выбросить исключение
    int result = 10 / 0;
} catch (ArithmeticException e) {
    // обработка конкретного типа
    System.out.println("Деление на ноль: " + e.getMessage());
} catch (Exception e) {
    // более общий тип — всегда ПОСЛЕ конкретных
    System.out.println("Что-то пошло не так");
} finally {
    // выполняется ВСЕГДА, даже если было исключение
    System.out.println("Конец блока");
}
// Multi-catch — одна обработка для нескольких типов
try {
    ...
} catch (IOException | NumberFormatException e) {
    System.out.println("Ошибка: " + e.getMessage());
}

Методы исключения

try {
    int[] arr = new int[3];
    arr[5] = 1;
} catch (ArrayIndexOutOfBoundsException e) {
    e.getMessage();     // "Index 5 out of bounds for length 3"
    e.printStackTrace();// вывести stacktrace в консоль
    e.getCause();       // причина (другое исключение) или null
}

finally всегда выполняется

public static int test() {
    try {
        return 1;        // собирается вернуть 1
    } finally {
        System.out.println("finally!");  // но сначала это
        // если здесь тоже return — перекроет return из try
    }
}
// Вывод: "finally!", вернёт 1

try-with-resources

Для объектов, которые нужно закрыть (реализуют AutoCloseable).
Закрывает ресурс автоматически, даже при исключении.

// Старый способ — надо закрывать вручную
Scanner sc = null;
try {
    sc = new Scanner(new File("file.txt"));
    System.out.println(sc.nextLine());
} catch (FileNotFoundException e) {
    e.printStackTrace();
} finally {
    if (sc != null) sc.close();
}

// Новый способ — try-with-resources
try (Scanner sc = new Scanner(new File("file.txt"))) {
    System.out.println(sc.nextLine());
} catch (FileNotFoundException e) {
    e.printStackTrace();
}
// sc.close() вызовется автоматически

throw — выброс исключения

public static int divide(int a, int b) {
    if (b == 0) {
        throw new IllegalArgumentException("b не может быть 0");
    }
    return a / b;
}

divide(10, 0);  // выбросит IllegalArgumentException

throws — объявление checked исключения

// Метод МОЖЕТ выбросить IOException — вызывающий должен обработать
public static String readFile(String path) throws IOException {
    Scanner sc = new Scanner(new File(path));
    return sc.nextLine();
}

// Вызывающий обязан:
try {
    String line = readFile("test.txt");
} catch (IOException e) {
    System.out.println("Файл не найден");
}

Создание своего исключения

// Unchecked — наследуем RuntimeException
public class InsufficientFundsException extends RuntimeException {
    private final double amount;

    public InsufficientFundsException(double amount) {
        super("Недостаточно средств: " + amount);
        this.amount = amount;
    }

    public double getAmount() { return amount; }
}

// Использование
public void withdraw(double sum) {
    if (sum > balance) {
        throw new InsufficientFundsException(sum);
    }
    balance -= sum;
}

Частые исключения — что вызывает

NullPointerException — обращение к методу/полю null-объекта

String s = null;
s.length();     // NullPointerException

ArrayIndexOutOfBoundsException — индекс за границей

int[] arr = new int[3];
arr[5] = 1;     // ArrayIndexOutOfBoundsException

ClassCastException — неверное приведение типов

Object o = "hello";
Integer i = (Integer) o;  // ClassCastException

ArithmeticException — деление на ноль (только для int/long)

int x = 5 / 0;   // ArithmeticException
double y = 5.0 / 0; // Infinity — исключения НЕТ!

NumberFormatException — плохая строка в число

int n = Integer.parseInt("abc");  // NumberFormatException

StackOverflowError — бесконечная рекурсия

void infinite() { infinite(); }  // StackOverflowError

Итоги — правила

← Меню