try-catch блоки

Конструкция try-catch — основной инструмент обработки исключений в Java. В блок try помещается код, который потенциально может выбросить исключение, а в один или несколько блоков catch — реакция на конкретные типы ошибок.

С Java 7 появилась возможность ловить несколько типов исключений одним блоком через оператор | (multi-catch). Это сокращает дублирование кода, когда реакция на разные ошибки одинаковая.

Блок finally выполняется всегда — независимо от того, было ли выброшено исключение и было ли оно поймано. Это идеальное место для освобождения ресурсов (закрытие файлов, соединений).

Синтаксис

try {
    // потенциально опасный код
} catch (ТипА | ТипБ e) {     // multi-catch
    // общая обработка
} catch (ТипВ e) {
    // отдельная обработка
} finally {
    // освобождение ресурсов
}

Пример 1. Простой try-catch

public class ParseTemp {
    public static void main(String[] args) {
        String raw = "23.5C";
        try {
            double t = Double.parseDouble(raw);
            System.out.println("Температура: " + t);
        } catch (NumberFormatException e) {
            System.out.println("Не удалось разобрать значение: " + raw);
        }
    }
}

Output:

Не удалось разобрать значение: 23.5C

Пример 2. Multi-catch

public class MultiCatchExample {
    public static void main(String[] args) {
        String[] sensors = {"42", null, "abc"};
        for (String s : sensors) {
            try {
                int v = Integer.parseInt(s);
                System.out.println("Значение: " + v);
            } catch (NumberFormatException | NullPointerException e) {
                System.out.println("Пропущено (" + e.getClass().getSimpleName() + ")");
            }
        }
    }
}

Output:

Значение: 42
Пропущено (NullPointerException)
Пропущено (NumberFormatException)

Пример 3. Вложенные try-catch

public class NestedTry {
    public static void main(String[] args) {
        try {
            int[] data = {10, 20, 30};
            try {
                System.out.println(data[5]);
            } catch (ArrayIndexOutOfBoundsException e) {
                System.out.println("Внутренний catch: индекс");
            }
            int x = Integer.parseInt("abc");
        } catch (NumberFormatException e) {
            System.out.println("Внешний catch: число");
        }
    }
}

Output:

Внутренний catch: индекс
Внешний catch: число

Пример 4. try + catch + finally

public class FinallyDemo {
    static String readPin(int pin) {
        try {
            if (pin < 0) {
                throw new IllegalArgumentException("pin < 0");
            }
            return "HIGH";
        } catch (IllegalArgumentException e) {
            return "ERROR";
        } finally {
            System.out.println("Освободили GPIO " + pin);
        }
    }

    public static void main(String[] args) {
        System.out.println("Результат: " + readPin(13));
        System.out.println("Результат: " + readPin(-1));
    }
}

Output:

Освободили GPIO 13
Результат: HIGH
Освободили GPIO -1
Результат: ERROR

Пример 5. Возврат к нормальной работе

public class RecoveryExample {
    static int safeParse(String s, int fallback) {
        try {
            return Integer.parseInt(s);
        } catch (NumberFormatException e) {
            return fallback;
        }
    }

    public static void main(String[] args) {
        System.out.println(safeParse("100", 0));
        System.out.println(safeParse("xx",  0));
        System.out.println(safeParse(null,  -1));
    }
}

Output:

100
0
-1

Подводные камни

Предупреждение

  • Порядок ``catch``: компилятор не пропустит, если Exception стоит раньше его наследника.

  • Multi-catch требует, чтобы типы не были в отношении наследования — иначе ошибка компиляции.

  • Не пишите ``return`` в ``finally`` — он перезатрёт значение из try или поглотит исключение.

  • Переменная multi-catch неявно ``final`` — её нельзя переприсвоить.

  • ``System.exit(0)`` в ``try`` — единственный случай, когда finally не выполнится.

См. также

Примечание

Материал подготовлен на основе официальной документации Oracle Java Tutorials — The try-catch Block (Oracle Free Documentation License). Текст переведён и переработан, примеры кода написаны заново.