У меня есть попытка/поймать с возвратом внутри. Будет ли выполняться блок finally?
try {
something();
return success;
}
catch (Exception e) {
return failure;
}
finally {
System.out.println("No se si esto se va a imprimir.");
}
Я знаю, что могу написать это и посмотреть, что произойдет (что я и собираюсь сделать), но когда я погуглил, ничего не вышло, поэтому я задал вопрос здесь.
Это вопрос, переведенный с оригинала на английский язык и адаптированный к результатам, которые он дает на моем компьютере: Всегда ли finally выполняется на Java? Джонни Пять
наконец позовут.
Единственные случаи, когда, наконец, не будет выполнено, это когда:
Этот ответ является переводом оригинального английского языка jodonnell .
Отредактировано 12.02.15: Учитывая , выполняется ли блок finally, если поток, выполняющий функцию, прерывается? Субхраджьоти Маджумдер
Очень простой вопрос, основанный на принципах Java, всегда будет вызываться блок finally .
Пока он закомментирован, вы заканчиваете выполнение кода или есть ошибки.
Дополнительная информация: Блок «Наконец»
НЕ ВСЕГДА
Спецификация языка Java описывает, как работают блоки try-catch-finally и try-finally, в разделе 14.20.2 .
Нигде не указано, что finally всегда выполняется.
Но он определяет это для всех случаев, когда блок try-catch-finally или try-finally завершается до того, как должен быть выполнен блок finally.
А именно. Если SIG — это то, что будет выполняться после блока try-catch-finally или try-finally, а FIN — это то, что находится внутри finally, JLS гарантирует, что FIN всегда выполняется до выполнения SIG .
Почему JLS не гарантирует, что блок finally всегда будет выполняться после блока try? Потому что это невозможно. Маловероятно, но возможно, что виртуальная машина будет прервана (убийство, сбой, выключение компьютера) сразу после завершения блока try и до выполнения блока finally. И нет ничего, что можно было бы сделать из спецификации языка, чтобы избежать этого.
Внутри блока
try / catch
finally
он всегда выполняется, как сказано в документации по Java :Примечание. Если JVM завершает работу во время выполнения кода try или catch, то блок finally не может быть выполнен . Аналогичным образом, если поток, выполняющий код , прерывается
try
илиcatch
уничтожается, блок finally не может выполняться, даже если приложение в целом продолжает работу .Начиная с Java SE 7, он «наконец» потерял известность.
До Java SE 7 можно было реализовать использование
finally
в качестве ключевого инструмента для предотвращения утечек ресурсов . При закрытии файла или извлечении ресурсов рекомендуется помещать код в блокfinally
, чтобы гарантировать, что ресурс всегда будет извлечен или закрыт.Поскольку он
finally
всегда выполняется, независимо от того, завершается ли операторtry
нормально или внезапно, этоfinally
был единственный возможный вариант гарантировать, что ресурс в конечном итоге будет закрыт.Мы видим это в следующем примере:
До Java 7
finally
это помогало нам избавиться от всех открытых ресурсов.Начиная с Java 7 был реализован оператор try-with-resources.
Оператор
try-with-resources
— это операторtry
, объявляющий один или несколько ресурсов. Ресурс — это объект, который должен быть закрыт после завершения программы . Оператор try-with-resources гарантирует, что каждый ресурс будет закрыт в конце оператора. Любой объект, реализующийjava.lang.AutoCloseable
, включая все объекты, реализующиеjava.io.Closeable
, может использоваться как ресурс.В следующем примере считывается первая строка из файла. Использует экземпляр
BufferedReader
для чтения данных из файла.BufferedReader
это ресурс, который должен быть закрыт после завершения программы:В этом примере ресурс, объявленный в операторе
try-with-resources
, представляет собой файлBufferedReader
. Оператор объявления появляется в круглых скобках сразу после ключевого словаtry
. КлассBufferedReader
в Java SE 7 и более поздних версиях реализует интерфейсjava.lang.AutoCloseable
. Поскольку экземплярBufferedReader
объявлен в оператореtry-with-resources
, он завершится независимо от того, завершается ли оператор try нормально или внезапно (в результате того, что методBufferedReader.readLine
выдает aIOException
).