Встречается на 75% собеседований по Java

В чем разница между checked и unchecked исключениями

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

Как это работает

В Java иерархия исключений строится на базе класса Throwable. От него наследуются два основных подкласса: Exception и Error. В свою очередь, Exception делится на две ветви:

  • Checked exceptions — все классы, наследующие Exception, но не наследующие RuntimeException. К ним относятся IOException, SQLException, ClassNotFoundException и другие.
  • Unchecked exceptions — это RuntimeException и все его наследники, а также Error и его наследники. Примеры: NullPointerException, ArrayIndexOutOfBoundsException, ArithmeticException, OutOfMemoryError.

Компилятор проверяет, что checked-исключения обработаны: либо в блоке try-catch, либо объявлены в сигнатуре метода через throws. Если этого не сделать, код не скомпилируется. Для unchecked-исключений такой проверки нет: их можно не обрабатывать и не объявлять.

Примеры

Checked исключение:

java
import java.io.*;

public class FileReader {
    public static void main(String[] args) {
        try {
            FileInputStream file = new FileInputStream("non_existent.txt");
        } catch (FileNotFoundException e) {
            System.out.println("Файл не найден: " + e.getMessage());
        }
    }
}

Здесь FileNotFoundException — checked-исключение, поэтому без try-catch или throws программа не скомпилируется.

Unchecked исключение:

java
public class Division {
    public static void main(String[] args) {
        int result = 10 / 0; // ArithmeticException
    }
}

ArithmeticException — unchecked, код компилируется, но при выполнении выбрасывается исключение.

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

  • Чрезмерная обработка unchecked-исключений. Некоторые разработчики оборачивают в try-catch даже NullPointerException, что скрывает ошибки программирования. Лучше исправлять причину, а не ловить следствие.
  • Игнорирование checked-исключений. Иногда проще добавить throws Exception в сигнатуру, но это перекладывает проблему на вызывающий код и ухудшает читаемость.
  • Путаница между Error и Exception. Error (например, OutOfMemoryError) — это серьёзные проблемы JVM, которые обычно не стоит обрабатывать. Их относят к unchecked, но они не являются исключениями в смысле бизнес-логики.
  • Собственные исключения. При создании своего класса исключения нужно решить, наследовать Exception (checked) или RuntimeException (unchecked). Часто для ошибок бизнес-логики выбирают unchecked, чтобы не загромождать код обязательными try-catch.

Когда использовать

  • Checked — для ошибок, которые программа может разумно обработать и восстановиться: отсутствие файла, неверный формат данных, сбой сети. Такие исключения заставляют разработчика явно продумать сценарий ошибки.
  • Unchecked — для ошибок, которые обычно нельзя исправить на месте: деление на ноль, выход за границы массива, неверный аргумент. Они сигнализируют о багах, которые нужно исправить в коде, а не обрабатывать.

Коротко

  • Checked-исключения обязаны быть обработаны (try-catch) или объявлены (throws); unchecked — нет.
  • Checked наследуют Exception (кроме RuntimeException); unchecked — RuntimeException и Error.
  • Checked — внешние ошибки, которые можно предвидеть; unchecked — ошибки программирования.
  • При создании своих исключений выбирайте тип по смыслу: checked для восстанавливаемых ошибок, unchecked для ошибок, которые лучше исправлять.
как отвечать на вопрос
пример собеседования
фреймворки на собеседовании
типичные вопросы junior
интервью вопросы и ответы