Что такое исключение (Exception) в Java?

Ответ

Исключение (Exception) в Java — это объект, который сигнализирует о возникновении аномальной или исключительной ситуации во время выполнения программы, прерывающей нормальный поток инструкций. Механизм исключений позволяет централизованно и структурированно обрабатывать ошибки.

Иерархия: Все исключения являются подклассами Throwable. Два основных подтипа:

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

Базовый шаблон обработки:

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("Ошибка ввода-вывода.");
} finally {
    // Код, выполняющийся всегда (например, для закрытия ресурсов)
    if (fis != null) fis.close();
}

Принципы использования:

  • Используйте проверяемые исключения для ожидаемых ошибок, от которых можно восстановиться.
  • Используйте непроверяемые исключения для ошибок программирования (предусловия, инварианты).
  • Предпочитайте специфичные исключения более общим.
  • В catch-блоках либо восстановите состояние, либо залогируйте ошибку и пробросьте её дальше.

Ответ 18+ 🔞

Давай разберём эту тему, как будто я тебе на кухне объясняю, с паяльником в одной руке и пивом в другой. Про исключения в Java.

Представь себе, что твоя программа — это такой идеальный, отлаженный механизм, как часы. Всё тикает, всё работает. А потом, блядь, случается какая-то хуйня. Например, файл, который ты пытаешься прочитать, внезапно оказался удалён. Или от сервера прилетает не JSON, а какая-то манда с ушами. Вот эта самая хуйня — это и есть исключение (Exception). Это не просто ошибка, а специальный объект, который кричит: «Э, сабака, сука, тут пиздец случился, дальше так нельзя!».

Иерархия, или кто на ком стоял

Все эти вопли о помощи происходят от одного общего предка — Throwable. А от него уже идут две главные ветви, как в плохой семье:

  1. Error — это когда уже всё, пиздец, капец, накрылось медным тазом. OutOfMemoryError, StackOverflowError. Это не ошибка логики, это крах всей виртуальной машины. Ловить это — всё равно что пытаться поймать руками падающий с неба двигатель. Бесполезно. Просто смотри и охуевай.

  2. Exception — а вот это уже наша тема. Ситуации, с которыми можно и нужно бороться. Но и тут, блядь, не всё просто. Они делятся на:

    • Проверяемые (Checked). Это такие занудные исключения, которые компилятор тебе в лицо тычет ещё до запуска. «Ты куда, мудак? — кричит он. — Ты же IOException не обработал! Или в throws не объявил! Я тебя не скомпилирую, пока ты не разберёшься!». Примеры: IOException, SQLException. Это для ситуаций, от которых теоретически можно отойти — файл не найден, сеть упала.
    • Непроверяемые (Unchecked). А вот это уже чисто наши, программистские, косяки. Наследники RuntimeException. Компилятор на них смотрит сквозь пальцы: «Делай что хочешь, потом сам разберёшься». А потом в рантайме вылезает NullPointerException и ебёт тебя в сраку. Или ArrayIndexOutOfBoundsException. Или ты передал в метод хуйню вместо числа — лови IllegalArgumentException. Волнение ебать, когда видишь это в логах продакшена.

Как со всем этим жить? Базовый шаблон.

Вот смотри, классическая схема, как не облажаться:

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("Ой, всё! Какая-то ошибка ввода-вывода.");
} finally {
    // А этот кусок кода — святой. Он выполнится ВСЕГДА.
    // Даже если в try всё взорвалось, даже если в catch мы словили исключение.
    // Идеальное место, чтобы прибраться за собой. Закрыть файлы, соединения, сеть.
    if (fis != null) {
        try {
            fis.close();
        } catch (IOException ignore) { /* Ну, закрыться не получилось, да похуй уже */ }
    }
}

Негласные правила, чтобы не выглядеть пидарасом шерстяным:

  • Проверяемые исключения — для тех ошибок, после которых программа ещё может как-то жить и не умирать. Сеть упала — переподключимся. Файла нет — спросим у пользователя другой.
  • Непроверяемые исключения — это твой позор. Это ошибки в логике, которые ты, мудак, должен был предусмотреть. null не проверял, индексы за границы массива лезут. Используй их для защиты своих методов от дурака (предусловия).
  • Лови конкретное, а не общее. Не надо ловить просто Exception и радоваться. Это как лечить всё подряд одним йодом. Поймал FileNotFoundException — скажи «файла нет». Поймал SocketTimeoutException — скажи «сервер уснул». Иначе потом будешь гадать, что же именно сломалось. Подозрение ебать чувствую, когда вижу catch (Exception e).
  • В catch-блоке не молчи. Либо реально исправь ситуацию (восстанови соединение), либо залогируй ошибку подробно (со стектрейсом, блядь!) и либо выйди gracefully, либо пробрось исключение дальше (throw e). Пустой catch — это высшая форма пидарасизма. Ты просто прячешь проблему под ковёр, а потом она вылезет в другом месте, и ты будешь три дня искать, откуда ноги растут. Сам от себя охуеешь.

Вот и вся философия. Не бойся исключений, они твои друзья. Они показывают, где твой код — говно. Главное — уметь их правильно слушать и не доводить до состояния «терпения ноль ебать».