Короткий ответ
Разница — в том, проверяет ли исключение компилятор. Checked-исключения проверяются на этапе компиляции: их нужно обработать в try-catch или объявить в throws, иначе код не соберётся. Unchecked-исключения (RuntimeException и её наследники, а также Error) компилятор не проверяет: они возникают в рантайме, и обрабатывать их не обязательно.
Как это работает подробнее
Checked-исключения — подклассы Exception, кроме RuntimeException: IOException, SQLException, ClassNotFoundException, InterruptedException и другие. Они обычно сигнализируют о проблемах внешней среды (файл не найден, сеть недоступна), поэтому язык заставляет разработчика обрабатывать их явно.
Unchecked-исключения — RuntimeException и все её наследники (NullPointerException, ArithmeticException, ArrayIndexOutOfBoundsException, NumberFormatException, ClassCastException), а также Error и его наследники. Они, как правило, означают ошибки логики или программиста: обработка и объявление в throws не обязательны.
Пример кода
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
public class CheckedVsUnchecked {
// checked: компилятор заставит обработать или объявить throws
void readFile(String path) throws IOException {
Files.readAllLines(Path.of(path));
}
// unchecked: компилируется без обработки, упадёт в рантайме
int div(int a, int b) {
return a / b; // ArithmeticException при b == 0
}
}Что использовать на практике
- Checked-исключения применяйте там, где вызывающий может осмысленно восстановиться: ввод-вывод, сеть, работа с БД.
- Ошибки программиста (невалидные аргументы, некорректное состояние) моделируйте unchecked-исключениями, например
IllegalArgumentException.