Когда в Java следует выбрасывать проверяемое (checked), а когда непроверяемое (unchecked) исключение?

«Когда в Java следует выбрасывать проверяемое (checked), а когда непроверяемое (unchecked) исключение?» — вопрос из категории Java Core, который задают на 10% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Выбор зависит от природы ошибки и ответственности за её обработку.

Проверяемые исключения (checked, например, IOException) следует использовать, когда:

  • Ошибка является ожидаемой частью работы метода (например, файл не найден, сетевое соединение разорвано).
  • Клиентский код может и должен осмысленно обработать эту ситуацию и восстановить работу.
  • Компилятор принуждает обработать исключение через try-catch или объявить в throws.
// Проверяемое исключение — клиент должен решить, что делать, если файла нет
public String readConfigFile(String path) throws IOException {
    return Files.readString(Paths.get(path));
}

Непроверяемые исключения (unchecked, наследники RuntimeException) следует использовать, когда:

  • Ошибка указывает на ошибку программиста или некорректное состояние программы (например, передача null в метод, требующий не-null, деление на ноль).
  • Обработка на месте обычно невозможна или нецелесообразна — это баг, который нужно исправить.
  • Компилятор не требует явной обработки.
// Непроверяемое исключение — программист передал недопустимый аргумент
public void setDiscount(double discount) {
    if (discount < 0 || discount > 1) {
        throw new IllegalArgumentException("Discount must be between 0 and 1");
    }
    this.discount = discount;
}

Практическое правило: Используйте checked исключения для восстанавливаемых условий, а unchecked — для ошибок программирования.