как использовать наконец - PullRequest
37 голосов
/ 28 июля 2010

Я никогда не понимал, как правильно использовать оператор finally.Может кто-нибудь сказать мне, в чем разница между:

try {
    a;
    block;
    off;
    statements;
} catch (Exception e) {
    handle;
    exception;
    e;
} finally {
    do;
    some;
    cleanup;
}

с одной стороны и:

try {
    a;
    block;
    off;
    statements;
} catch (Exception e) {
    handle;
    exception;
    e;
}
do;
some;
cleanup;

с другой

Ответы [ 9 ]

36 голосов
/ 01 августа 2010

Они отличаются, если

  • try -блок завершается броском java.lang.Throwable, который не является java.lang.Exception, например, потому что это java.lang.Error, например AssertionErrorили OutOfMemoryError.
  • блок try завершается внезапно, используя оператор потока управления, такой как continue, break или return
  • блок catch завершается внезапно (бросаялюбой бросаемый или использующий оператор потока управления)

В целом, язык Java гарантирует, что блок finally выполняется до завершения оператора try.(Обратите внимание, что, если оператор try не завершен, нет гарантии относительно оператора finally. Оператор может не завершиться по ряду причин, включая завершение работы оборудования, завершение работы ОС, завершение работы виртуальной машины (например, из-за System.exit),ожидающий поток (Thread.suspend(), synchronized, Object.wait(), Thread.sleep()) или занятый другим образом (бесконечные циклы ,,,).

Таким образом, блок finally является лучшим местомдля действий по очистке, чем конец тела метода, но сам по себе, все еще не может гарантировать очистку exeuction.

29 голосов
/ 28 июля 2010

finally блок выполняется всегда.

Блок

finally используется для очистки, например, для освобождения ресурсов, используемых в try / catch, закрытия соединений с БД, закрытия сокетов и т. Д., Даже если в вашем try / * 1008 происходит необработанное исключение * блок.

Единственный раз, когда блок finally не выполняется, это когда system.exit() вызывается в try / catch или вместо исключения возникает некоторая ошибка.

Ошибка в приведенном выше описании означает, что приложение Java завершает работу с такими условиями, как ошибка Out Of Memory. Я вижу некоторые отрицательные отзывы :( по этой причине кажется.

18 голосов
/ 28 июля 2010

Основное отличие состоит в том, что секция catch сама может выдать исключение, выйти из окружающего блока или вернуться из текущего метода.В этом случае do; some; cleanup; не выполняется.

С блоком finally гарантировано , что этот код будет выполнен.

11 голосов
/ 28 июля 2010

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

Также:

  • Блок catch может выдать исключение
  • Возможно, вы захотите вернуться из блока try

Короче говоря, если вы хотите, чтобы какой-то код выполнялся, когда вы выходите из блока try / catch , однако вы его покидаете (кроме очень трудного завершения процесса), наконец, ваш друг.

8 голосов
/ 28 июля 2010

В правильном стиле кодирования вы не хотите делать перехват всех, как показано ниже.

try{
  [some task] 
}
catch
{
}

Что вы хотели бы сделать, это перехватить определенные известные ошибки.

try{
  [some task] 
}
catch(Exception ex)
{
   if([known execption])
     [ignore]
   else
     throw(ex);
}
[Cleanup]

В этом случае ваш код очистки не будет запущен в случае повторной выдачи ошибки.Таким образом, мы добавляем функцию finally, которая будет запущена, даже если выдается новая ошибка.

try{
  [some task] 
}
catch(Exception ex)
{
   if([known execption])
     [ignore]
   else
     throw(ex);
}
finally
{
   [Cleanup]
}
7 голосов
/ 28 июля 2010

Блок finally будет всегда выполняться.

Во втором примере очистка не будет происходить, если блок catch перебрасывает исключение или если в блоке try произошло необработанное исключение.

3 голосов
/ 28 июля 2010

Из этого форума на GeekInterview:

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

1 голос
/ 28 июля 2010

Просто одна строка объяснения:

независимо от того, поймали ли вы исключение или нет, коды в блоке finally будут выполнены.

разница между двумя фрагментами, которые вы здесь дали, такова: коды в фрагменте без использования finally никогда не будут выполнены.

чтобы правильно понять finally, все, что вам нужно знать, это то, что finally = гарантия!

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

0 голосов
/ 28 июля 2010

В первом примере блок finally всегда выполняется, даже если у вас есть оператор return в предложении try. Единственный раз, когда он не выполняется, это когда у вас есть System.exit (0).

...