Сколько операторов в выражении try / catch? - PullRequest
7 голосов
/ 18 января 2010

Должен ли я поместить несколько операторов в попытку и затем перехватить все возможные исключения, или мне следует добавить только одну инструкцию в инструкцию try?

Пример:

try {
    MaybeThrowIOException();
    MaybeThrowFooBarException();
    return true;
} catch (IOException e) {
    // ...
} catch (FooBarException e) {
   // ... 
}

Или

try {
    MaybeThrowIOException();
} catch (IOException e) {
    // ...
}

try {
    MaybeThrowFooBarException();
} catch (FooBarException e) {
   // ... 
}

return true;

Ответы [ 13 ]

7 голосов
/ 18 января 2010

Оберните ваши критические части , чтобы ваше сообщение было четким и понятным.

3 голосов
/ 18 января 2010

Это зависит от случая, но важно отметить, что в первом случае MaybeThrowFooBarException () вызывается недопустимо, если MaybeThrowIOException () выдает исключение, а во втором случае MaybeThrowFooBarException всегда будет называться , если исключение переброшено в первом улове

3 голосов
/ 18 января 2010

Чем больше утверждений вы добавите, тем менее конкретным может быть причина исключения.

Но, конечно, это зависит от того, содержат ли вызовы / операторы функций перекрывающиеся исключения, т. Е. Если все исключения могут быть учтены определенным образом, то все равно все в порядке.

В вашем примере вы, похоже, имеете неперекрывающиеся исключения, поэтому ваша первая форма в порядке.

2 голосов
/ 18 января 2010

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

Итак, мой голос - пример №2.

1 голос
/ 18 января 2010

Вы можете обрабатывать несколько типов исключений с помощью одного цикла try / catch.Но позаботьтесь о порядке, в котором вы собираетесь обрабатывать исключения.Порядок блока исключений улова имеет значение.

0 голосов
/ 18 января 2010

Если метод, который вы вызываете, может возвращать FooExeption () и BarException () и вы хотите перехватить оба, тогда первый пример имеет смысл - довольно много API делают это, особенно те, которые имеют более высокий уровень сами используют больше вещей, которые могут вызывать исключения).

Если вы делаете две разные вещи, то это действительно полностью зависит от того, какой результат вы хотите получить:

  • Если исключение в конечном итоге равносильно тому, что касается вашего кода, и вы не заботитесь о том, чтобы откатить что-либо (или просто откатить с любого, и вы можете легко сделать это в одном блоке finally - при условии, что язык поддерживает это), тогда нет смысла иметь два отдельных блока try / catch.

  • Если типы ошибок очень разнообразны, и вас волнует, что произойдет, если первый метод вызовет исключение (например, и потребуется выполнить некоторые операции для отката), и вы хотите продолжить выполнение второй операции, даже если первый бросил исключение, тогда второй подход был бы более уместным.

  • Если вам небезразлично, если первый метод завершится неудачно, и вы не хотите продолжать выполнение, если это произойдет, то стоит помнить, что вы можете вкладывать try / catch, хотя с этим лучше не переусердствовать При правильном использовании это гораздо понятнее, чем пытаться следовать инструкциям bools, если операторы проверяют, должен ли блок выполняться или нет.

, например

try {

    MaybeThrowFooException();

    try {
    // Will only be called as long as MaybeThrowFooException() is not thrown
        MaybeThrowBarException();

    } catch (BarException ex) {

    }

} catch (FooException ex) {

}
0 голосов
/ 18 января 2010

Если они действительно такие отдельные, то первое - это лучшая практика, просто потому что это короче.

Однако, если MaybeThrowIOException() может сгенерировать FooBarException или MaybeThrowFooBarException() сгенерировать IOException, то вам следует только обернуть их вместе, если вы хотите, чтобы они оба выполнили одно и то же действие исключение!

0 голосов
/ 18 января 2010

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

0 голосов
/ 18 января 2010

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

Либо разделите 2 вызова на 2 отдельных метода, либо используйте первый подход.

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

0 голосов
/ 18 января 2010

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

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

...