Что такое проверяемые исключения (checked exceptions) в Java и как с ними работать?

Ответ

Проверяемые исключения (checked exceptions) — это исключения, которые компилятор Java обязывает обрабатывать или объявлять в сигнатуре метода с помощью throws. Они представляют собой ожидаемые ошибки восстановимого характера (например, проблемы ввода-вывода).

Ключевые аспекты работы:

  • Объявление: Класс исключения должен наследоваться от java.lang.Exception (но не от RuntimeException).
  • Обработка: Вы должны либо обработать исключение в блоке try-catch, либо объявить его в сигнатуре метода с ключевым словом throws.
  • Best Practice: Используйте проверяемые исключения для ошибок, от которых вызывающий код может разумно восстановиться. Избегайте злоупотребления ими для контроля потока выполнения.

Пример:

// Метод объявляет проверяемое исключение
public String readFile(String path) throws IOException {
    return Files.readString(Paths.get(path));
}

// Вызывающий код обязан его обработать
public void processFile() {
    try {
        String content = readFile("data.txt");
    } catch (IOException e) {
        // Восстановление: логирование и использование значения по умолчанию
        System.err.println("File not found, using default.");
        content = "default";
    }
}

Ответ 18+ 🔞

А, вот эта тема, про которую все такие умные книжки пишут, а на деле-то всё просто, как три копейки. Проверяемые исключения, блядь. Это как тебе бабушка в детстве говорила: "Взял ведро — неси, а то по ебалу получишь". Компилятор Java — он как та самая бабушка, только вместо ведра — исключение, а вместо ебла — красная подчёркивающая хуйня в IDE.

Суть, если по-простому: Это такие ошибки, которые компилятор видит заранее и требует с тебя расписки, что ты о них знаешь. Типа, "чувак, ты сейчас файл читать собрался, а он может и не найтись, ёпта. Так что либо лови эту хрень, либо предупреди всех, что ты такой рискованный тип".

Как с ними жить, не сойдя с ума:

  • Родословная: Чтобы исключение было "проверяемым", его папкой должен быть java.lang.Exception. Не RuntimeException — это уже другая, более либеральная ветвь семьи.
  • Выбор без выбора: У тебя два пути, оба ведут в ад, но разный. Либо ты оборачиваешь опасный код в try-catch и там разбираешься с последствиями. Либо ты пишешь в объявлении метода throws ТупаяОшибка и перекладываешь эту проблему на того, кто твой метод вызовет. А тот — на своего соседа. И так до бесконечности, пока кто-то не наступит на грабли.
  • Мудрость веков (aka Best Practice): Используй эту хуйню только для ошибок, от которых правда можно оправиться. Файл не найден? Можно сказать пользователю "выбери другой". Сеть легла? Можно попробовать переподключиться. А вот если ты NullPointerException сделаешь проверяемым — это уже клинический идиотизм, это всё равно что требовать расписку за то, что дышать собрался.

Смотри, как это выглядит вживую:

// Твой метод. Он опасный, как хуй в стеклянной посуде.
// Ты честно предупреждаешь всех: "Братки, я могу швырнуть IOException!"
public String прочитатьФайл(String путь) throws IOException {
    return Files.readString(Paths.get(путь)); // Тут всё может пойти по пизде
}

// А вот тот, кто это использует. Ему теперь волей-неволей приходится думать.
public void обработатьФайл() {
    try {
        String содержимое = прочитатьФайл("данные.txt");
        // Ура, пронесло!
    } catch (IOException e) {
        // А вот и не пронесло. Ну что ж, восстанавливаемся, как можем.
        // Логируем, что мы лузеры...
        System.err.println("Файла нет, ёпта! Работаем по-старинке.");
        // ...и используем заглушку.
        содержимое = "значение_по_умолчанию";
    }
}

Вот и вся философия. Не сделаешь как надо — компилятор тебя просто не пустит в runtime, будет орать как резаный, пока не исправишь. Иногда это бесит, но, блядь, от глупых ошибок спасает.