Ответ
Выбор зависит от природы ошибки и ответственности за её обработку.
Проверяемые исключения (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 — для ошибок программирования.
Ответ 18+ 🔞
О, слушай, а вот это, блядь, тема, про которую можно дохуя спорить, но на самом деле всё просто, как три копейки. Выбор между checked и unchecked исключениями — это не просто так, сука, "ой, а давайте кину вот это". Это про ответственность, ёпта. Кто за что в ответе?
Проверяемые исключения (checked, типа IOException) — это когда ты, сука, предупреждаешь всех заранее: "Эй, народ, тут может случиться такая вот ожидаемая хуйня, будьте готовы!" Это часть контракта метода, блядь.
- Когда юзать? Когда ошибка — это нормальная, ожидаемая часть работы, а не пиздец. Файл не нашли? Сеть отвалилась? Пользователь ввёл хуйню в конфиг? Да, бывает, сука. Жизнь такая.
- Кто отвечает? Тот, кто вызывает твой метод. Компилятор ему в ебальник тычет: "Мужик, либо обработай эту ситуацию в
try-catch, либо сам объяви, что кидаешь её дальше (throws). Решай, нахуй, что делать". Клиентский код может и должен как-то отреагировать.
// Проверяемое исключение. Говоришь всем: "Братан, файл может и не быть, не удивляйся"
public String readConfigFile(String path) throws IOException {
return Files.readString(Paths.get(path)); // Может выстрелить, и это ок
}
Непроверяемые исключения (unchecked, наследники RuntimeException) — это уже, блядь, крик души: "ААА, КТО ТУТ УРОД ПРОГРАММУ ПИСАЛ?!" Это про ошибки в логике, про пиздец в состоянии программы.
- Когда юзать? Когда наступил на грабли, которые сам же и разложил. Передал
nullтуда, где он не жилец. Делишь на ноль. Индекс за границы массива полез. Это баг, ёпта. Ошибка программиста. - Кто отвечает? Тот, кто этот баг допустил. Обрабатывать это на месте — обычно бесполезно. Надо не
try-catchписать, а идти чинить свой кривой код. Компилятор тебя за руку не ловит — ты сам себе злой буратино.
// Непроверяемое исключение. Это пиздец, а не ошибка.
public void setDiscount(double discount) {
if (discount < 0 || discount > 1) {
// Кричишь тому, кто это вызвал: "Ты чё, больной? Откуда у тебя скидка 200%?"
throw new IllegalArgumentException("Discount must be between 0 and 1");
}
this.discount = discount;
}
Короче, практическое правило, которое даже обезьяна поймёт:
- Checked (проверяемые) — для проблем, которые можно пережить. "Файла нет? Ну ок, спросим у пользователя путь ещё раз".
- Unchecked (непроверяемые) — для пиздеца, который надо чинить. "На ноль делим? Да иди ты нахуй, исправляй свой алгоритм".
Всё. А то начнёшь IllegalArgumentException в throws пихать — выглядеть будешь как манда с ушами.