3. Обгортання винятків
Checked-винятки здавалися чимось класним у теорії та виявилися повним розчаруванням на практиці.
Припустимо, у вас у проєкті є суперпопулярний метод, який викликається із сотень місць програми. І ви вирішили додати в нього новий checked-виняток. І цілком може виявитися, що цей checked-виняток дійсно такий важливий і особливий, що тільки метод main() знає, що робити у разі захоплення цього винятку.
Тому вам доведеться додати checked-винятки в throws
всіх методів, які викликають ваш суперпопулярний метод. А також в throws
всіх методів, які викликають ті методи. І в методи, які викликають ті методи.
В результаті у вас в throws
у половини методів проєкту буде доданий новий checked-виняток. А потім виявиться, що у вас проєкт покритий тестами, і тести не компілюються. І
вам доведеться правити throws ще й у тестах.
А потім весь ваш код (зміни в сотнях файлів) повинні будуть рев’ювити інші програмісти. І тут ми запитуємо себе: а заради чого ми вносили в проєкт дохреналіон змін? День(дні?) роботи, зламані тести, і все заради додавання одного checked-винятку??
Адже є ще проблеми з наслідуванням та перевизначенням методів. Проблем від checked-винятків набагато більше, ніж користі. Загалом зараз мало хто їх любить і мало хто використовує.
Однак все ще багато кодів (зокрема код стандартних бібліотек Java) містять ці самі checked-винятки. І що ж із ними робити? Ігнорувати не можна, обробляти – невідомо як.
Java-програмісти запропонували «загортати» checked-винятки всередину
RuntimeException
. Інакше кажучи, перехоплювати всі checked-винятки, створювати
замість них unchecked-винятки (наприклад, RuntimeException
) і викидати вже їх.
Виглядає все це приблизно так:
try
{
код, де може виникнути checked-виняток
}
catch(Exception exp)
{
throw new RuntimeException(exp);
}
Не дуже красиве рішення, але нічого кримінального: виняток просто поклали всередину винятку
RuntimeException
.
За бажання його можна звідти легко дістати. Приклад:
Код | Примітка |
---|---|
|
Отримуємо виняток, збережений всередині об’єкта RuntimeException . cause може бути null Визначаємо його тип та перетворюємо до змінної checked -типу. |