Сколько операторов в операторе попытки/выгоды?

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

Пример:

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

Или

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

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

return true;
7
задан jcjr 21 September 2017 в 16:19
поделиться

13 ответов

-

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

7
ответ дан 6 December 2019 в 12:51
поделиться

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

-121--3866415-

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

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

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

-121--3866411-

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

Однако, если ThrowIOxception () может выдать FooBarException или ThrowFooBarException () выдать IOExeption , то их следует объединять только в том случае, если вы хотите, чтобы они оба взяли

0
ответ дан 6 December 2019 в 12:51
поделиться

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

0
ответ дан 6 December 2019 в 12:51
поделиться

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

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

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

-121--3866411-

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

0
ответ дан 6 December 2019 в 12:51
поделиться

Поскольку MySQL перестроит всю таблицу при внесении изменений в схему.

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

-121--2698840-

Для контрастирования ответа @ khelll используются переменные экземпляра объектов Class:

class Fish
  # an instance variable of this Class object
  @var = 'fish'

  # the "getter"
  def self.v
    @var
  end

  # the "setter"
  def self.v=(a_fish)
    @var = a_fish
  end
end

class Trout < Fish
  self.v = 'trout'
end

class Salmon < Fish
  self.v = 'salmon'
end

p Trout.v   # => "trout"
p Salmon.v  # => "salmon"

Edit: , чтобы предоставить экземплярам доступ для чтения к переменной экземпляра класса:

class Fish
  def type_of_fish
    self.class.v
  end
end

p Trout.new.type_of_fish   # => "trout"
p Salmon.new.type_of_fish  # => "salmon"
-121--1617038-

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

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

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

3
ответ дан 6 December 2019 в 12:51
поделиться

В соответствии с тем, что Jldupont говорит, я стараюсь всегда отделить свои потенциальные заявления о рисках в несколько блоков TRY / CALL. Таким образом, когда что-то пойдет не так, вы знаете точно , где это было, и вы можете иметь конкретные сообщения об ошибках для каждой проблемы.

0
ответ дан 6 December 2019 в 12:51
поделиться
- 3879813-

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

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

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

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

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

E.g.

try {

    MaybeThrowFooException();

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

    } catch (BarException ex) {

    }

} catch (FooException ex) {

}
0
ответ дан 6 December 2019 в 12:51
поделиться

Поскольку MySQL перестроит всю таблицу при внесении изменений в схему.

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

-121--2698840-

Для контраста ответа @ khelll используются переменные экземпляра объектов Class:

class Fish
  # an instance variable of this Class object
  @var = 'fish'

  # the "getter"
  def self.v
    @var
  end

  # the "setter"
  def self.v=(a_fish)
    @var = a_fish
  end
end

class Trout < Fish
  self.v = 'trout'
end

class Salmon < Fish
  self.v = 'salmon'
end

p Trout.v   # => "trout"
p Salmon.v  # => "salmon"

Edit: , чтобы предоставить экземплярам доступ для чтения к переменной экземпляра класса:

class Fish
  def type_of_fish
    self.class.v
  end
end

p Trout.new.type_of_fish   # => "trout"
p Salmon.new.type_of_fish  # => "salmon"
-121--1617038-

можно использовать любой из них.

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

0
ответ дан 6 December 2019 в 12:51
поделиться

Для сравнения ответа @ khelll используются переменные экземпляра объектов Class:

class Fish
  # an instance variable of this Class object
  @var = 'fish'

  # the "getter"
  def self.v
    @var
  end

  # the "setter"
  def self.v=(a_fish)
    @var = a_fish
  end
end

class Trout < Fish
  self.v = 'trout'
end

class Salmon < Fish
  self.v = 'salmon'
end

p Trout.v   # => "trout"
p Salmon.v  # => "salmon"

Edit: , чтобы предоставить экземплярам доступ для чтения к переменной экземпляра класса:

class Fish
  def type_of_fish
    self.class.v
  end
end

p Trout.new.type_of_fish   # => "trout"
p Salmon.new.type_of_fish  # => "salmon"
-121--1617038-

можно использовать любой из них.

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

-121--3866412-

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

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

0
ответ дан 6 December 2019 в 12:51
поделиться

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

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

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

0
ответ дан 6 December 2019 в 12:51
поделиться

Вы можете обрабатывать несколько типов исключений через петлю Single Try / Catch. Но позаботьтесь о том, чтобы вы собираетесь справиться с исключениями. Порядок блока исключения Catch имеет значение.

1
ответ дан 6 December 2019 в 12:51
поделиться

«Довольно скоро» - довольно расплывчатая спецификация, но сборщик мусора, вероятно, не так быстр, как вы, кажется, ожидаете. Когда объекты действительно будут собраны, многое зависит от конфигурации GC и загрузки сервера, но это может занять некоторое время, и если у вашей виртуальной машины достаточно кучи и другие вещи для этого, объекты не будут собраны «довольно скоро».

Единственная ситуация, когда спецификация ВМ гарантирует, что GC будет запущен, это когда в какой-то пункт в противном случае будет вызвана ошибка OutOfMemureError. Перед отправкой OutOfMemureError виртуальная машина обязана предпринять попытку собрать, по крайней мере, столько подходящих экземпляров объектов, чтобы соответствующий запрос на выделение памяти мог быть успешным (но вам все еще не гарантировано, что будут собраны все подходящие экземпляры).

-121--2695416-

Интересный вопрос, и я не уверен, что это возможно, но я предполагаю начать с просмотра интерфейсов IMarkupLoader и IMarkupResoureStreamProvider и реализующих классов и посмотреть, как далеко вы оттуда доберетесь.
Мне было бы интересно все, что вы найдете/реализуете, что на самом деле делает это!

-121--2485103-

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

Таким образом, мой голос - пример # 2.

2
ответ дан 6 December 2019 в 12:51
поделиться

Это зависит В случае, но важно отметить, что в первом случае maybethrowfoobarexception () является Nerver под названием, если maybethrowioException () бросает исключение, а во втором случае maybethrowfoobarexception будет выпущен , если исключение первый улов

3
ответ дан 6 December 2019 в 12:51
поделиться
Другие вопросы по тегам:

Похожие вопросы: