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-типа. |