Когда использовать многократный захват, а когда - переброс?

Я очень не уверен в этих двух темах. Я знаю, что мне следует использовать множественный захват для исключений, которые должны обрабатываться одинаково. Но зачем мне что-то подобное.

private void something(String name) throws IOException, RemoteException {
    try {
        ...
    } catch (Exception ex) {

        ... // do something

        throw ex;
    }
}

person LaBlum    schedule 17.04.2017    source источник
comment
Однако использование общего исключения - плохая практика. См. здесь.   -  person Enzokie    schedule 17.04.2017
comment
Разве этот вопрос не является одновременно непонятным и основанным на мнении?   -  person Ole V.V.    schedule 17.04.2017


Ответы (3)


Вы можете сделать это, если считаете, что для этого метода любое исключение, созданное во время его выполнения, должно обрабатываться таким же образом, и вы хотите выполнить задачу, прежде чем разрешить распространять исключение на клиент

Например, предположим, что вы хотите выполнить определенную обработку при возникновении исключения, такую ​​как запись информации в журнал. Итак, вы поймаете его, чтобы выполнить эту задачу.
Тем не менее вы считаете, что перехваченное исключение является проблемой и что регистрация этого исключения не была «реальной» обработкой исключения. Итак, вы позволяете ему размножаться, повторно бросая его.

person davidxxx    schedule 17.04.2017
comment
Хорошо спасибо. Но могу я задать еще один вопрос? Предположим, что исключение NullPointerException было выброшено и перехвачено уловкой. Будет ли это исключение также выброшено в вызывающий метод, потому что в предложении throws упоминаются только IO- и RemoteException? Привет из Германии - person LaBlum; 17.04.2017
comment
Пожалуйста. Очень интересный вопрос. NullPointerException - это RuntimeException. Этот вид исключения не нужно явно объявлять в объявлении метода. Вы можете бросить его, не ловя его и не объявив метод как бросающий. В отличие от IOException и RemoteException, которые являются отмеченными исключениями. Последние происходят только от Exception, а не от RuntimeException. - person davidxxx; 17.04.2017
comment
Это правда ... я не считал это. И что произойдет, если будет выбрано исключение IllegalArgumentException, например, потому что я хотел сохранить строку в переменной типа int? Будет ли он в любом случае передан вызывающему методу, хотя он не упоминается в предложении throws? - person LaBlum; 17.04.2017
comment
Конечно, он будет передан вызывающему методу, но поскольку это RuntimeException, вызывающий может решить не обрабатывать его. Если вы хотите, чтобы исключение было обработано (выброшено или перехвачено), вы должны использовать проверенное исключение (... extends Exception). Не стесняйтесь создавать собственные, если это вам подходит. - person davidxxx; 17.04.2017
comment
Это было неуклюже с моей стороны. xD Я забыл, что это тоже RuntimeException. На самом деле я хотел спросить, что произойдет, если проверенное исключение произойдет в блоке try и передано блоку catch, а затем передано вызывающему методу без упоминания этого в предложении throws. Короче говоря, я, наконец, протестировал его, и ответ (как вы уже упоминали ранее) следующий: когда я выбрасываю проверенное исключение, то независимо от того, упоминается ли исключение в предложении throws, вызывающий метод должен обрабатывать это само по себе. xD Большое спасибо! - person LaBlum; 17.04.2017
comment
Часто лучший способ понять это - попробовать :) Добро пожаловать :) - person davidxxx; 17.04.2017
comment
Я считаю «зарегистрировать и повторно выбросить» явный анти-шаблон и способ заполнить ваш журнал бесполезным материалом, который, в конце концов, может затруднить поиск того, что вам нужно среди мусора. Вызывающий, который в конце перехватывает и обрабатывает исключение, может гораздо лучше решить, нужно ли и как его регистрировать. И при правильной цепочке исключений он может регистрировать каждую деталь, если это необходимо. - person Ole V.V.; 18.04.2017

Вам потребуется переброс в следующих ситуациях

  1. Вы хотите что-то предварительно обработать, прежде чем позволить исключению покинуть метод. Однако, если вам не важен тип исключения, предварительная обработка также может выполняться в блоке finally.
  2. Вы пытаетесь преобразовать отмеченные исключения в непроверенное исключение. В этом случае вы будете перехватывать все исключения как catch(Exception ex) и повторно генерировать их как throw new RuntimeException(ex).
  3. Вы хотите, чтобы ваше собственное исключение выдавалось вместо встроенных. Таким образом, вы поймаете все исключения, а затем создадите свой собственный объект исключения, желательно не отмеченный, и выбросите его. Многие API-интерфейсы делают это, например Spring преобразует JDBC непонятные исключения в настраиваемые исключения Spring.
  4. Это что-то вроде предварительной обработки. Вы хотите отслеживать все исключения, создаваемые путем создания ArrayList или чего-то еще, чтобы в конце программы с несколькими шагами вы знали, какие шаги вызывают исключения. Я видел, как это использовалось в Talend сгенерированном коде Java.
person 11thdimension    schedule 17.04.2017

ReThrow

Всякий раз, когда вы хотите уведомить вызывающий метод об исключении, вы перехватываете и повторно генерируете исключение.

Скажем, какой-то метод callSomething () вызывает ваш метод something (). Если какое-либо исключение происходит внутри something (), оно просто перехватит исключение, чтобы приложение не завершилось ошибкой, и повторно выбросит его в метод callSomething (). Затем callSomething () уведомит клиента о внутренней ошибке.

Другой пример: в шаблоне MVC запрос, отправленный клиентом, обслуживается каким-либо методом из контроллера на основе сопоставления запроса. Контроллер вызовет службу, и служба будет взаимодействовать с некоторым методом dao. Если в DAO возникает какое-то исключение, то DAO повторно выбрасывает исключение в службу, служба перенаправляет на контроллер, и именно контроллер уведомляет клиента о сообщении об ошибке. В java это называется распространением исключений. Исключение распространяется от метода к методу вверх по стеку вызовов, пока не будет обнаружено.

Мульти улов

Если вы хотите выполнить одно и то же действие для нескольких типов исключений, используйте multi catch.

person adi    schedule 17.04.2017