Какой смысл наконец блока?

В таких случаях общий трюк (был?) для возврата назад:

for(int i = l.size() - 1; i >= 0; i --) {
  if (l.get(i) == 5) {
    l.remove(i);
  }
}

Тем не менее, я более чем счастлив, что у вас есть лучшие способы в Java 8, например. removeIf или filter в потоках.

30
задан Bill the Lizard 20 November 2011 в 13:43
поделиться

16 ответов

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

Во втором примере, если код в возвратах блока выгоды или выходах, x = 3 не будет выполняться. В первом это будет.

В платформе.NET, в некоторых случаях выполнение наконец блок не произойдет: Исключения безопасности, приостановки Потока, Компьютерное закрытие:), и т.д.

34
ответ дан Vinko Vrsalovic 27 November 2019 в 23:05
поделиться

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

, Например, закрыв сеанс базы данных или соединение JMS, или освобождая некоторый ресурс ОС.

я предполагаю, что это подобно в.NET?

0
ответ дан Uri 27 November 2019 в 23:05
поделиться

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

, @mats очень корректен, что всегда существует потенциал для "твердых" отказов - наконец, блоки не должны включать код в жестком реальном времени, который должен всегда делаться транзакционно в попытке {}

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

try
{
StreamReader stream = new StreamReader("foo.bar");
mySendSomethingToStream(stream);
}
catch(noSomethingToSendException e) {
    //Swallow this    
    logger.error(e.getMessage());
}
catch(anotherTypeOfException e) {
    //More serious, throw this one back
    throw(e);
}
finally
{
stream.close();
}

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

1
ответ дан Ian 27 November 2019 в 23:05
поделиться

Любой код в наконец, работал в даже в случае необработанного исключения. Обычно наконец код используется для чистки локальных объявлений неуправляемого кода с помощью .dispose ().

0
ответ дан osp70 27 November 2019 в 23:05
поделиться

Наконец блок находится в том же объеме как попытка/выгода, таким образом, у Вас будет доступ ко всем переменным определенным внутри.

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

try
{
   StreamReader stream = new StreamReader("foo.bar");
   stream.write("foo");
}
catch(Exception e) { } // ignore for now
finally
{
   stream.close();
}

по сравнению с

StreamReader stream = null;
try
{
    stream = new StreamReader("foo.bar");
    stream.write("foo");
} catch(Exception e) {} // ignore

if (stream != null)
    stream.close();

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

0
ответ дан Mats Fredriksson 27 November 2019 в 23:05
поделиться

@Ed, Вы могли бы думать о чем-то как catch(...), который ловит неуказанное исключение в C++.

, Но finally код, который будет выполнен, неважно, что происходит в эти catch блоки.

Microsoft имеет страницу справки на попытка наконец C#

0
ответ дан Community 27 November 2019 в 23:05
поделиться

Таким образом, можно очистить любые открытые соединения, и т.д. инициализированные в блоке попытки. Если бы Вы открыли соединение, и затем исключение произошло, то исключение не было бы правильно закрыто. Этот тип сценария - то, для чего наконец блок.

0
ответ дан Ryan Lanciaux 27 November 2019 в 23:05
поделиться

Наконец блок, как предполагается, выполняется, поймали ли Вы исключение или нет. См. Попытка / Выгода / Наконец пример

0
ответ дан NotMe 27 November 2019 в 23:05
поделиться

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

1
ответ дан Moe 27 November 2019 в 23:05
поделиться

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

, Если Вы, например, выдайте новое Исключение в своем catchblock (перебросок), чем присвоение будет только выполняться, если это будет в наконец-блоке.

Обычно наконец используется для чистки после себя (близкие соединения с БД, Дескрипторы файлов и подобные).

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

2
ответ дан Mo. 27 November 2019 в 23:05
поделиться

попробуйте выгоду наконец , довольно важная конструкция. Можно быть уверены, что, даже если исключение выдается, код в наконец блоке будет выполнен. Очень важно в обработке внешних ресурсов выпустить их. Сборка "мусора" не сделает этого для Вас. В наконец части Вы не должны иметь возврат операторы или выдавать исключения. Возможно сделать это, но это - плохая практика и может привести к непредсказуемым результатам.

, Если Вы пробуете этот пример:

try {
  return 0;
} finally {
  return 2;
}

результат будет 2:)

Сравнение с другими языками: Возврат От Наконец

9
ответ дан Bartosz Bierkowski 27 November 2019 в 23:05
поделиться

Существует несколько вещей, которые делают наконец блок полезный:

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

Они делают наконец блоки превосходными для закрытия дескрипторов файлов или сокетов.

6
ответ дан wvdschel 27 November 2019 в 23:05
поделиться

В Java:

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

10
ответ дан SCdF 27 November 2019 в 23:05
поделиться

Ну, с одной стороны, если Вы ВОЗВРАТИТЕСЬ в своем блоке попытки, то наконец будет все еще работать, но код упомянул ниже try-catch-finally блок, не будет.

37
ответ дан Josh Hinman 27 November 2019 в 23:05
поделиться

@iAn и @mats:

я ничего не "разъединил" бы в наконец {}, который был "настроен" в рамках попытки {}, как правило. Было бы лучше для получения по запросу потокового создания за пределами попытки {}. Если необходимо обработать исключение, в действии создают, это могло бы быть сделано в большем объеме.

StreamReader stream = new StreamReader("foo.bar");  
try {
    mySendSomethingToStream(stream);
}
catch(noSomethingToSendException e) {
    //Swallow this    
    logger.error(e.getMessage());
}
catch(anotherTypeOfException e) {
    //More serious, throw this one back
    throw(e);
}
finally {
    stream.close();  
}
1
ответ дан Sean 27 November 2019 в 23:05
поделиться

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

Это не ответ. Я действительно думаю, что нет никакой положительной стороны к finally, который может быть, почему это не существовало на языках программирования до "недавно". Большинство примеров, указывающих stream.close(), может вызвать исключения нулевой ссылки, таким образом, все еще необходимо протестировать, если это является пустым.

Да, если Вы возвращаетесь из try{}, finally все еще выполнения. Но то, что хорошая практика? Это походит на gynastics, мог бы также принести goto назад. Почему бы не ожидать и возврат после блока? Весь finally {} делает, добавляют две или три строки к Вашему коду.

1
ответ дан 27 November 2019 в 23:05
поделиться
Другие вопросы по тегам:

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