Java Try Catch finally блокирует без Catch


125

Я просматриваю новый код. В программе есть только блок попыток и окончание. Поскольку блок catch исключен, как работает блок try, если он встречает исключение или что-то бросаемое? Он просто переходит непосредственно в блок finally?



25
@mP Каждый должен делать обзоры кода и задавать им вопросы - это как учиться и совершенствоваться.
Карл Притчетт

Ответы:


130

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

Блок finally всегда выполняется, независимо от того, выброшено исключение или нет.


11
Первый абзац не обязательно верен. Блоки try могут быть вложенными. Любое неперехваченное исключение, не отмеченное флажком или нет, выскочит из метода.
Энди Томас

4
Блоки try могут быть вложенными, но я бы не рекомендовал это делать. Я так не пишу код.
duffymo

2
@duffymo: Что значит «выскочить из метода»?
Сегодня я заработал

5
@Anand просто немного нетехнический язык для "выброса исключения".
duffymo

2
Не игнорируется; передать цепочку методов.
duffymo

93

Небольшое примечание по try/ finally: finally всегда будет выполняться, если

  • System.exit() называется.
  • JVM дает сбой.
  • В try{}блоке не заканчивается (например , бесконечный цикл).

4
О чем try{..} catch{ throw ..} finally{..}? Думаю ваще не исполнят
сбеляков

10
В таком случае, наконец, все равно будет называться. Только исходное исключение теряется.
Питер Лоури,

Наконец, также не будет выполняться, если вы вызовете System.exit () раньше.
mmirror 01

2
@jyw Это то, что я имел в виду под первым элементом в списке выше.
Питер Лоури

Я должен сказать, это охватывает все основы!
Оскар Браво

39

Спецификация языка Java (1) описывает, как try-catch-finallyвыполняется. Отсутствие улова эквивалентно отсутствию улова, способного поймать данный Throwable.

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

(1) Выполнение try-catch-finally


16

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

public class TryCatchFinally {

  public static void main(String[] args) throws Exception {

    try{
        System.out.println('A');
        try{
            System.out.println('B');
            throw new Exception("threw exception in B");
        }
        finally
        {
            System.out.println('X');
        }
        //any code here in the first try block 
        //is unreachable if an exception occurs in the second try block
    }
    catch(Exception e)
    {
        System.out.println('Y');
    }
    finally
    {
        System.out.println('Z');
    }
  }
}

Результаты в

A
B
X
Y
Z

6

Блок finally всегда запускается после завершения блока try, независимо от того, заканчивается ли попытка нормально или ненормально из-за исключения, например, throwable.

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

Если блок finally выдает исключение / ошибку / выброс и уже есть ожидающий выброс, он становится некрасивым. Откровенно говоря, я забываю, что именно происходит (так много лет назад я получил сертификат). Я думаю, что обе метательные объекты связаны друг с другом, но есть какое-то особое колдовство, которое вам нужно сделать (то есть - вызов метода, который мне нужно было бы найти), чтобы получить исходную проблему до того, как "наконец-то" вырвало, э-э ...

Между прочим, try / finally - довольно распространенная вещь для управления ресурсами, поскольку в java нет деструкторов.

Например -

r = new LeakyThing();
try { useResource( r); }
finally { r.release(); }  // close, destroy, etc

«Наконец», еще один совет: если вы действительно потрудились поставить в улове, либо поймать конкретный (ожидается) Throwable подклассов, или просто поймать «Throwable», не «Исключение», для общего приема всей ловушки ошибок. Слишком много проблем, таких как тупицы с отражением, выбрасывают «Ошибки», а не «Исключения», и они ускользнут от любого «улова всех», закодированного как:

catch ( Exception e) ...  // doesn't really catch *all*, eh?

сделайте это вместо этого:

catch ( Throwable t) ...

См. Ответ Карлоса Хойбергера ниже для уродливой части.
mplwork 05

3

Версии Java до версии 7 допускают эти три комбинации try-catch-finally ...

try - catch
try - catch - finally
try - finally

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

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

  • За блоком попытки Java должен следовать блок catch или finally.
  • Для каждого блока try может быть ноль или более блоков catch, но только один блок finally.
  • Блок finally не будет выполнен, если программа завершится (либо путем вызова System.exit (), либо из-за фатальной ошибки, вызывающей прерывание процесса).

1
"до версии 7 разрешить" вы подразумеваете, что Java 7 и Java 8 не допускают эти три комбинации? Я сомневаюсь, что вы это имеете в виду, но ваш ответ подразумевает именно это.
Loduwijk

выполняется ли блок finally, если в блоке try есть оператор возврата?
Рахул Ядав

@Rahul Да, наконец-то назовут. Ссылка: stackoverflow.com/questions/65035/…
roottraveller

1
@Aaron - новый синтаксис для try-with-resource, который автоматически вызывает .close () для всего, что построено в скобках сразу после ключевого слова try.
Roboprog

2

как работает блок try, если он встречает исключение или что-то бросаемое

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

Блок finally выполняется независимо от того, как завершается блок try - независимо от того, есть ли вообще какие-либо уловки, независимо от того, есть ли совпадающий улов.

Блоки catch и finally являются ортогональными частями блока try. Вы можете иметь одно или оба. С Java 7 у вас не будет ни того, ни другого!


1

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


1

Блок finally выполняется после завершения блока try. Если что-то брошено внутри блока try, когда оно выходит, выполняется блок finally.


0

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

Теперь, если у нас есть блок try-finally вместо блока try-catch-finally, то исключение не будет обрабатываться, и после блока try вместо блока управления, собирающегося перехватить блок, оно перейдет в блок finally. Мы можем использовать блок try-finally, когда мы не хотим ничего делать за исключением.


0

Независимо от того, выброшено исключение или нет в tryблоке - finallyблок будет выполнен. Исключение не будет обнаружено.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.