Каковы причины исключения, которые не могут быть совместимы с предложениями бросков?
Может ли кто-нибудь сказать мне, какие причины могут иметь исключения, а не быть совместимыми с предложениями "броски"
Например:
class Sub extends Super{
@Override
void foo() throws Exception{
}
}
class Super{
void foo() throws IOException{
}
}
Исключение исключений несовместимо с предложением throws в Super.foo()
Ответы
Ответ 1
Без полного примера кода я могу только догадываться: вы переопределяете/реализуете метод в подклассе, но спецификация исключения для метода подкласса несовместима с (т.е. не подмножеством) класса суперкласса/интерфейса метод?
Это может произойти, если базовый метод объявлен вообще не выдавать исключений, или, например, java.io.IOException
(который является подклассом java.lang.Exception
, который пытается использовать ваш метод). Клиенты базового класса/интерфейса ожидают, что его экземпляры будут соответствовать контракту, объявленному базовым методом, поэтому выброс Exception
из реализации этого метода приведет к разорению контракта (и LSP).
Ответ 2
Проверенные исключения предназначены для использования в ситуациях, когда метод может ожидать, что его вызывающий абонент будет готов к решению определенных проблем, которые могут возникнуть. Если вызывающим абонентам BaseFoo.Bar()
не требуется иметь дело с FnordException
, тогда метод DerivedFoo.Bar()
не может ожидать, что его вызывающие стороны будут иметь дело с FnordException
либо (так как многие из его вызывающих абонентов будут теми же, которые были не готовы BaseFoo.Bar()
выбросить его).
Концептуально, это здорово. На практике это не так много. Проблема в том, что дизайн проверенных исключений на языке предполагает, что ни один из вызывающих абонентов не будет готов грамотно обрабатывать определенную проблему, или все абоненты будут готовы справиться с этим. Нормальное состояние дел на практике заключается в том, что вызывающие абоненты не готовы к устранению исключений - даже тех, которые могут обрабатывать некоторые вызывающие абоненты. В большинстве случаев правильный ход действий, когда код получает проверенное исключение, которое явно не ожидало, было бы обернуть его в неконтролируемое исключение и выбросить его. По иронии судьбы, самый простой способ действий - добавление предложения "бросает" и возможность вычеркнуть проверенное исключение, вероятно, является наименее вероятным. Хотя существует несколько случаев (например, IOException
), где такое поведение имеет смысл (например, при попытке прочитать коллекцию из файла ошибка ввода-вывода при чтении одного элемента является ошибкой ввода-вывода при чтении коллекции) исключение, вызванное вызовом вложенного метода, будет представлять собой другое условие, чем исключение того же типа, которое было бы выбрано внешним методом, и код, который будет подготовлен для обработки последнего, может быть не подготовлен к обработке первого.
В вашей ситуации лучше всего поймать IOException
и обернуть его каким-то другим типом, который происходит от RuntimeException
, осознавая, что ваши вызывающие лица вряд ли смогут его обработать.
Ответ 3
Чтобы исправить это, используйте RuntimeException
public T findById(long id) throws RuntimeException {
try {
return whatEver.create();
} catch (SystemException e) {
throw new RuntimeException(e);
}
}
Надеюсь, что это поможет.
Ответ 4
Удостоверьтесь, что вы объявили о выбросе вашего интерфейса. Если вы это сделали, но проблема все еще сохраняется - попробуйте сохранить/перестроить проект.