Какой базовый механизм обработки исключений (exception handling) в Java?

Ответ

Базовый механизм строится на трех ключевых блоках: try, catch, finally и ключевых словах throw и throws.

1. Блок try-catch-finally:

try {
    // Код, который может вызвать исключение (опасная операция)
    FileInputStream fis = new FileInputStream("file.txt");
    int data = fis.read();
} catch (FileNotFoundException e) {
    // Обработка конкретного checked-исключения
    System.err.println("Файл не найден: " + e.getMessage());
} catch (IOException e) {
    // Обработка более общего checked-исключения
    System.err.println("Ошибка ввода-вывода: " + e.getMessage());
} catch (Exception e) {
    // "Корзинка" для любых других исключений (не рекомендуется для повседневного использования)
    System.err.println("Неизвестная ошибка: " + e);
} finally {
    // Блок выполняется ВСЕГДА, даже если было исключение или return
    // Используется для освобождения ресурсов (закрытие файлов, соединений)
    if (fis != null) {
        try { fis.close(); } catch (IOException e) { /* логирование */ }
    }
}

2. Классификация исключений:

  • Checked Exceptions (Exception): Компилятор обязывает их обрабатывать (try-catch) или объявлять в сигнатуре метода (throws). Пример: IOException, SQLException. Представляют ожидаемые ошибки внешних условий.
  • Unchecked Exceptions (RuntimeException): Не требуют обязательной обработки. Пример: NullPointerException, IllegalArgumentException, ArithmeticException. Чаще всего указывают на ошибки программиста.
  • Error: Критические системные ошибки, которые обычно не обрабатываются (например, OutOfMemoryError, StackOverflowError).

3. Проброс исключений (throws):

public void readFile() throws FileNotFoundException, IOException {
    // Метод не обрабатывает исключения, а передает их вызывающему коду
    FileInputStream fis = new FileInputStream("file.txt");
    // ...
}

4. Выброс исключения (throw):

if (value < 0) {
    throw new IllegalArgumentException("Значение не может быть отрицательным: " + value);
}

Best Practice: Всегда старайтесь обрабатывать исключения на том уровне, где есть достаточно информации для принятия осмысленного решения (логирование, повторная попытка, возврат пользователю понятной ошибки).

Ответ 18+ 🔞

А, исключения в Java! Ну это ж классика, блядь, ёпта! Сидишь ты такой, пишешь код, всё летает, а потом — хрясь! — и тебе в ебало NullPointerException прилетает. Как будто хуй с горы на голову упал. Давай разбираться, как с этой пиздой работать, чтобы не обосраться.

Смотри, основа всего этого цирка — три блока: try, catch и finally. Плюс два ключевых слова: throw и throws. Запоминай, а то потом будешь как Герасим — «Му-му» говорить, а нихуя не понимать.

1. Блок try-catch-finally: Вот смотри, как это выглядит вживую:

try {
    // Тут код, который может всё похерить. Опасная операция.
    FileInputStream fis = new FileInputStream("file.txt");
    int data = fis.read();
} catch (FileNotFoundException e) {
    // Ловим конкретную хуйню — файл не нашли.
    System.err.println("Файл не найден: " + e.getMessage());
} catch (IOException e) {
    // Ловим что-то более общее — ошибку ввода-вывода.
    System.err.println("Ошибка ввода-вывода: " + e.getMessage());
} catch (Exception e) {
    // А это — универсальная помойка. Сюда слетается всякая дичь.
    // Для ежедневного использования — так себе идея, но бывает.
    System.err.println("Неизвестная ошибка: " + e);
} finally {
    // А вот это, сука, святое! Выполняется ВСЕГДА.
    // Даже если всё пошло по пизде и вылетело исключение.
    // Даже если ты в блоке `try` написал `return`.
    // Место, чтобы прибраться за собой: закрыть файлы, соединения и т.д.
    if (fis != null) {
        try { fis.close(); } catch (IOException e) { /* просто залогируй, не рыпайся */ }
    }
}

2. Какие бывают исключения (классификация, блядь):

  • Checked Exceptions (Exception): Это такие зануды. Компилятор, сука, стоит у тебя над душой и требует: либо оберни в try-catch, либо объяви в сигнатуре метода через throws. Примеры: IOException, SQLException. Это обычно ожидаемые косяки внешнего мира — файла нет, сеть легла.
  • Unchecked Exceptions (RuntimeException): А вот это уже поинтереснее. Компилятор на них забивает хуй. Но если вылезут — будет больно. NullPointerException, IllegalArgumentException, ArithmeticException (деление на ноль, ёпта!). Чаще всего это твои собственные косяки в логике.
  • Error: Это уже пиздец полный. Системные ошибки, с которыми обычно нихуя не поделаешь: OutOfMemoryError (память кончилась), StackOverflowError (ушел в бесконечную рекурсию, гений). Их даже ловить не советуют.

3. Проброс исключений дальше (throws): Иногда проще не париться и скинуть проблему на того, кто тебя вызвал. Делается так:

public void readFile() throws FileNotFoundException, IOException {
    // Я, блядь, тут ничего не обрабатываю!
    // Пусть тот, кто меня дернул, сам разбирается со своими файлами.
    FileInputStream fis = new FileInputStream("file.txt");
    // ...
}

4. Самому выкинуть исключение (throw): А бывает, ты сам понимаешь, что дальше работать нельзя. Тогда ты становишься источником проблем:

if (value < 0) {
    // Всё, пиздец, я не могу с этим работать.
    throw new IllegalArgumentException("Значение не может быть отрицательным: " + value);
}

Главное правило (best practice, как они говорят): Обрабатывай исключения там, где у тебя есть хоть какая-то информация, что с этим делать. Не просто глотай их молча, а то потом будешь дебажить три дня, ебать мои старые костыли. Либо логируй понятно, либо пробуй заново, либо возвращай пользователю человеческое сообщение, а не stack trace. И да, finally — твой лучший друг для уборки, не забывай про него, а то ресурсы потекут.