В чем разница между 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 исключение:
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 исключение:
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 для ошибок, которые лучше исправлять.
