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

<p>учитывая этот код, могу ли я быть <em>абсолютно уверен</em> в том, что блок <code>finally</code> всегда выполняется, независимо от того, что такое <code>something()</code>?</p><pre><code>try { something(); return success; } catch (exception e) { return failure; } finally { system.out.println("i don't know if this will get printed out"); } </code></pre>

<p>да, <code>finally</code> будет вызываться после выполнения блоков кода <code>try</code> или <code>catch</code>.</p><p>единственное время, когда <code>finally</code> не будет вызвано:</p><ol> <li>если вы вызываете <code>system.exit()</code></li> <li>если jvm падает в первую очередь</li> <li>если jvm достигает бесконечного цикла (или другого непрерываемого, не завершающего оператора) в блоке <code>try</code> или <code>catch</code></li> <li>если ос принудительно завершает процесс jvm; например, <code>kill -9 <pid></code> в unix</li> <li>если хост-система умирает; например, сбой питания, аппаратная ошибка, паника ос и т. д.</li> <li>если блок <code>finally</code> будет выполняться потоком демона и все остальные потоки, не являющиеся демонами, завершат работу до вызова <code>finally</code></li> </ol>

<p>пример кода:</p><pre><code>public static void main(string[] args) { system.out.println(test.test()); } public static int test() { try { return 0; } finally { system.out.println("finally trumps return."); } } </code></pre><p>результат:</p><pre class="lang-none prettyprint-override"><code>finally trumps return. 0 </code></pre>

<p>также, хотя это плохая практика, если в блоке finally есть оператор return, он превзойдет любой другой возврат из обычного блока. то есть следующий блок вернул бы false:</p><pre><code>try { return true; } finally { return false; } </code></pre><p>то же самое с выбросом исключений из блока finally.</p>

<p>вот официальные слова из спецификации языка [java].</p><p> <a href="https://docs.oracle.com/javase/specs/jls/se8/html/jls-14.html#jls-14.20.2">14.20.2. выполнение try-finally и try-catch-finally</a> </p><blockquote> <p><strong> оператор <code>try</code> с блоком <code>finally</code> выполняется первым выполнением блока <code>try</code>. тогда есть выбор: </strong></p> <ul> <li>если выполнение блока <code>try</code> завершается нормально, [...]</li> <li>если выполнение блока <code>try</code> завершается внезапно из-за <code>throw</code> значения <em>v</em>, [...]</li> <li><strong> если выполнение блока <code>try</code> завершается внезапно по любой другой причине <em>r</em>, то выполняется блок <code>finally</code>. тогда есть выбор: </strong> <ul> <li>если блок finally завершается нормально, тогда оператор <code>try</code> завершается внезапно по причине <em>r</em>.</li> <li>если блок <code>finally</code> завершается преждевременно по причине <em>s</em>, то оператор <code>try</code> завершается преждевременно по причине <em>s</em> (<strong> и причина <em>r</em> отбрасывается </strong>).</li> </ul> </li> </ul> </blockquote><p>спецификация для <code>return</code> фактически делает это явным:</p><p> <a href="https://docs.oracle.com/javase/specs/jls/se8/html/jls-14.html#jls-14.17">jls 14.17 отчет о возврате</a> </p><blockquote> <pre><code>returnstatement: return expression(opt) ; </code></pre> <p>оператор <code>return</code> без <code>expression</code> <strong> пытается </strong> передать управление вызывающему методу или конструктору, который его содержит.</p> <p>оператор <code>return</code> с <code>expression</code> <strong> пытается </strong> передать управление вызывающему методу, который его содержит; значение <code>expression</code> становится значением вызова метода.</p> <p>в предыдущих описаниях говорится "<em> <strong> попытки </strong> передать управление </em>" а не просто "<em> передает управление </em> "потому что если в методе или конструкторе есть какие-либо операторы <code>try</code>, чьи блоки <code>try</code> содержат оператор <code>return</code>, то любые операторы <code>finally</code> этих операторов <code>try</code> будут выполняться в порядке, от самого внутреннего до самого внешнего, перед управлением передается вызывающему методу или конструктору. внезапное завершение предложения <code>finally</code> может нарушить передачу управления, инициированную оператором <code>return</code>.</p> </blockquote>

<p>в дополнение к другим ответам важно указать, что 'finally' имеет право переопределить любое исключение/возвращаемое значение с помощью блока try..catch. например, следующий код возвращает 12:</p><pre><code>public static int getmonthsinyear() { try { return 10; } finally { return 12; } } </code></pre><p>аналогично, следующий метод не генерирует исключение:</p><pre><code>public static int getmonthsinyear() { try { throw new runtimeexception(); } finally { return 12; } } </code></pre><p>в то время как следующий метод бросает это:</p><pre><code>public static int getmonthsinyear() { try { return 12; } finally { throw new runtimeexception(); } } </code></pre>

<p>я попробовал приведенный выше пример с небольшой модификацией</p><pre><code>public static void main(final string[] args) { system.out.println(test()); } public static int test() { int i = 0; try { i = 2; return i; } finally { i = 12; system.out.println("finally trumps return."); } } </code></pre><p>вышеприведенный код выводит:</p><blockquote> <p>наконец козыри возвращаются.<br> 2</p> </blockquote><p>это связано с тем, что при выполнении <code>return i;</code> <code>i</code> имеет значение 2. после этого выполняется блок <code>finally</code>, где 12 присваивается <code>i</code>, а затем выполняется <code>system.out</code> out.</p><p>после выполнения блока <code>finally</code> блок <code>try</code> возвращает 2, а не 12, поскольку этот оператор return больше не выполняется.</p><p>если вы будете отлаживать этот код в eclipse, у вас будет ощущение, что после выполнения <code>system.out</code> блока <code>finally</code> оператор <code>return</code> блока <code>try</code> выполняется снова. но это не так. он просто возвращает значение 2.</p>

<p>вот разработка <a href="https://stackoverflow.com/a/65185/2684342">ответ кевина</a> . важно знать, что возвращаемое выражение вычисляется до <code>finally</code>, даже если оно возвращается после.</p><pre><code>public static void main(string[] args) { system.out.println(test.test()); } public static int printx() { system.out.println("x"); return 0; } public static int test() { try { return printx(); } finally { system.out.println("finally trumps return... sort of"); } } </code></pre><p>результат:</p><pre class="lang-none prettyprint-override"><code>x finally trumps return... sort of 0 </code></pre>

<p>вот и вся идея окончательного блока. это позволяет вам убедиться, что вы делаете очистки, которые в противном случае могли бы быть пропущены, потому что, конечно, вы возвращаетесь.</p><p>наконец, вызывается <strong>независимо от того, что происходит</strong> в блоке try (<em>, если </em> вы не вызовете <code>system.exit(int)</code> или java виртуальная машина вылетает по какой-то другой причине).</p>

<p>логичный способ думать об этом:</p><ol> <li>код, помещенный в блок finally, должен быть выполнен <strong>что бы ни происходило</strong> внутри блока try</li> <li>таким образом, если код в блоке try пытается вернуть значение или сгенерировать исключение, элемент помещается "на полку", пока блок finally не может быть выполнен</li> <li>поскольку код в блоке finally имеет (по определению) высокий приоритет, он может возвращать или выдавать все, что ему нравится. в этом случае все, что осталось "на полке", отбрасывается.</li> <li>единственным исключением является то, что vm полностью отключается во время блока try, например 'system.exit'</li> </ol>

<p>наконец, всегда выполняется finally, если нет ненормального завершения программы (например, вызов system.exit (0) ..). итак, ваш системник будет напечатан</p>

<p>также возврат в, наконец, отбросит любое исключение. <a href="http://jamesjava.blogspot.com/2006/03/dont-return-in-finally-clause.html">http://jamesjava.blogspot.com/2006/03/dont-return-in-finally-clause.html</a> </p>

<p>блок finally всегда выполняется, если не происходит аварийного завершения программы, вызванного сбоем jvm или вызовом <code>system.exit(0)</code>.</p><p>кроме того, любое значение, возвращаемое из блока finally, будет переопределять значение, возвращаемое до выполнения блока finally, поэтому будьте осторожны при проверке всех точек выхода при использовании try finally.</p>

<p>нет, не всегда одним случаем исключения является // system.exit (0); прежде чем блок finally не позволяет выполнить, наконец, finally.</p><pre><code> class a { public static void main(string args[]){ datainputstream cin = new datainputstream(system.in); try{ int i=integer.parseint(cin.readline()); }catch(arithmeticexception e){ }catch(exception e){ system.exit(0);//program terminates before executing finally block }finally{ system.out.println("won't be executed"); system.out.println("no error"); } } } </code></pre>

<p>наконец, всегда запускается, и в этом весь смысл, просто потому, что он появляется в коде после возврата, не означает, что так оно и реализовано. среда выполнения java отвечает за запуск этого кода при выходе из блока <code>try</code>.</p><p>например, если у вас есть следующее:</p><pre><code>int foo() { try { return 42; } finally { system.out.println("done"); } } </code></pre><p>среда выполнения сгенерирует что-то вроде этого:</p><pre><code>int foo() { int ret = 42; system.out.println("done"); return 42; } </code></pre><p>если генерируется неперехваченное исключение, блок <code>finally</code> будет запущен, и исключение продолжит распространяться.</p>

<p>это потому, что вы присвоили значение i как 12, но не вернули значение i в функцию. правильный код выглядит следующим образом:</p><pre><code>public static int test() { int i = 0; try { return i; } finally { i = 12; system.out.println("finally trumps return."); return i; } } </code></pre>

<p>потому что блок finally всегда будет вызываться, пока вы не вызовете <code>system.exit()</code> (или поток не завершится).</p>

<blockquote> <p>ответ прост <strong>да</strong>.</p> </blockquote><p><strong>вход:</strong></p><pre><code>try{ int dividebyzeroexception = 5 / 0; } catch (exception e){ system.out.println("catch"); return; // also tried with break; in switch-case, got same output } finally { system.out.println("finally"); } </code></pre><p><strong>результат:</strong></p><pre><code>catch finally </code></pre>

<p>да, это будет называться. в этом весь смысл ключевого слова finally. если выпрыгивание из блока try/catch может просто пропустить блок finally, это то же самое, что поместить system.out.println вне try/catch.</p>

<p>да, наконец, блок всегда выполняется. большинство разработчиков используют этот блок для закрытия соединения с базой данных, объекта набора результатов, объекта оператора, а также используют в спящем режиме java для отката транзакции.</p>

<p>вкратце, в официальной java документации (нажмите <a href="http://docs.oracle.com/javase/tutorial/essential/exceptions/finally.html">здесь</a> ) написано, что -</p><blockquote> <p>если jvm завершает работу во время выполнения кода try или catch, блок finally может не выполняться. аналогично, если поток, выполняющий код try или catch, прерывается или уничтожается, блок finally может не выполняться, даже если приложение в целом продолжается.</p> </blockquote>

<p>да, это будет. единственный случай, когда это не будет, jvm выходит или вылетает</p>

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

<p>рассмотрим следующую программу:</p><pre><code>public class sometest { private static stringbuilder sb = new stringbuilder(); public static void main(string args[]) { system.out.println(somestring()); system.out.println("---again---"); system.out.println(somestring()); system.out.println("---print the result---"); system.out.println(sb.tostring()); } private static string somestring() { try { sb.append("-abc-"); return sb.tostring(); } finally { sb.append("xyz"); } } } </code></pre><p>начиная с java 1.8.162, приведенный выше блок кода дает следующий вывод:</p><pre><code>-abc- ---again--- -abc-xyz-abc- ---print the result--- -abc-xyz-abc-xyz </code></pre><p>это означает, что использование <code>finally</code> для освобождения объектов является хорошей практикой, подобной следующему коду:</p><pre><code>private static string somestring() { stringbuilder sb = new stringbuilder(); try { sb.append("abc"); return sb.tostring(); } finally { sb = null; // just an example, but you can close streams or db connections this way. } } </code></pre>

<p>я попробовал это, это однопоточный.</p><pre><code>class test { public static void main(string args[]) throws exception { object obj = new object(); try { synchronized (obj) { obj.wait(); system.out.println("after wait()"); } } catch (exception e) { } finally { system.out.println("finally"); } } } </code></pre><p>основной поток будет находиться в состоянии ожидания навсегда, поэтому, наконец, никогда не будет вызван,</p><p>поэтому вывод консоли не будет печатать строку: <code>after wait()</code> или <code>finally</code></p><p>согласившись с @stephen c, приведенный выше пример является одним из упоминаний о 3-м случае <a href="https://stackoverflow.com/a/65049/2987755">здесь</a> :</p><p>добавим еще несколько таких возможностей бесконечного цикла в следующем коде:</p><pre><code>// import java.util.concurrent.semaphore; class test { public static void main(string[] args) { try { // thread.sleep(long.max\_value); // thread.currentthread().join(); // new semaphore(0).acquire(); // while (true){} system.out.println("after sleep join semaphore exit infinite while loop"); } catch (exception e) { } finally { system.out.println("finally"); } } } </code></pre><p>случай 2: если jvm падает первым</p><pre><code>import sun.misc.unsafe; import java.lang.reflect.field; class test { public static void main(string args[]) { try { unsafemethod(); // runtime.getruntime().halt(123); system.out.println("after jvm crash!"); } catch (exception e) { } finally { system.out.println("finally"); } } private static void unsafemethod() throws nosuchfieldexception, illegalaccessexception { field f = unsafe.class.getdeclaredfield("theunsafe"); f.setaccessible(true); unsafe unsafe = (unsafe) f.get(null); unsafe.putaddress(0, 0); } } </code></pre><p>ссылка: <a href="https://stackoverflow.com/q/65200/2987755">как вы разбили jvm?</a> </p><p>случай 6: если блок finally будет выполняться потоком демона, и все другие потоки, не являющиеся демонами, завершат работу до вызова finally.</p><pre><code>class test { public static void main(string args[]) { runnable runnable = new runnable() { @override public void run() { try { printthreads("daemon thread printing"); // just to ensure this thread will live longer than main thread thread.sleep(10000); } catch (exception e) { } finally { system.out.println("finally"); } } }; thread daemonthread = new thread(runnable); daemonthread.setdaemon(boolean.true); daemonthread.setname("my daemon thread"); daemonthread.start(); printthreads("main thread printing"); } private static synchronized void printthreads(string str) { system.out.println(str); int threadcount = 0; set<thread> threadset = thread.getallstacktraces().keyset(); for (thread t : threadset) { if (t.getthreadgroup() == thread.currentthread().getthreadgroup()) { system.out.println("thread :" + t + ":" + "state:" + t.getstate()); ++threadcount; } } system.out.println("thread count started by main thread:" + threadcount); system.out.println("-------------------------------------------------"); } } </code></pre><p>вывод: это не выводит "finally", что означает, что "блок finally" в "потоке демона" не был выполнен</p><blockquote> <pre><code>main thread printing thread :thread[my daemon thread,5,main]:state:blocked thread :thread[main,5,main]:state:runnable thread :thread[monitor ctrl-break,5,main]:state:runnable thread count started by main thread:3 ------------------------------------------------- daemon thread printing thread :thread[my daemon thread,5,main]:state:runnable thread :thread[monitor ctrl-break,5,main]:state:runnable thread count started by main thread:2 ------------------------------------------------- process finished with exit code 0 </code></pre></blockquote>

<p>да, потому что <strong>без управляющего оператора</strong> может помешать выполнению <code>finally</code>.</p><p>вот справочный пример, где все кодовые блоки будут выполнены:</p><pre><code>| x | current result | code |---|----------------|------ - - - | | | | | | public static int finallytest() { | 3 | | int x = 3; | | | try { | | | try { | 4 | | x++; | 4 | return 4 | return x; | | | } finally { | 3 | | x--; | 3 | throw | throw new runtimeexception("ahh!"); | | | } | | | } catch (runtimeexception e) { | 4 | return 4 | return ++x; | | | } finally { | 3 | | x--; | | | } | | | } | | | |---|----------------|------ - - - | | result: 4 | </code></pre><p>в приведенном ниже варианте <code>return x;</code> будет пропущен. результат по-прежнему <code>4</code>:</p><pre><code>public static int finallytest() { int x = 3; try { try { x++; if (true) throw new runtimeexception("ahh!"); return x; // skipped } finally { x--; } } catch (runtimeexception e) { return ++x; } finally { x--; } } </code></pre><p>ссылки, конечно же, отслеживают их статус. в этом примере возвращается ссылка с <code>value = 4</code>:</p><pre><code>static class intref { public int value; } public static intref finallytest() { intref x = new intref(); x.value = 3; try { return x; } finally { x.value++; // will be tracked even after return } } </code></pre>

<p><code>finally</code> будет выполнен, и это точно.</p><p><code>finally</code> не будет выполняться в следующих случаях:</p><p>случай 1 :</p><p>когда вы выполняете <code>system.exit()</code>.</p><p>случай 2:</p><p>когда ваша jvm/thread падает.</p><p>случай 3:</p><p>когда ваше выполнение остановлено между вручную.</p>

<p><code>try</code>- <code>catch</code>- <code>finally</code> - ключевые слова для использования случая обработки исключений.<br> как обычное объяснение</p><pre><code>try { //code statements //exception thrown here //lines not reached if exception thrown } catch (exception e) { //lines reached only when exception is thrown } finally { // always executed when the try block is exited //independent of an exception thrown or not } </code></pre><p>блок finally не позволяет выполнить ...</p><ul> <li>когда вы позвонили <code>system.exit(0);</code></li> <li>если jvm выходит.</li> <li>ошибки в jvm</li> </ul>

<p>если вы не обрабатываете исключение, перед завершением программы jvm выполняет блок finally. это не будет выполнено, только если нормальное выполнение программы не приведет к завершению программы по следующим причинам:.</p><ol> <li> <p>вызывая фатальную ошибку, которая приводит к прерыванию процесса.</p> </li> <li> <p>завершение программы из-за повреждения памяти.</p> </li> <li> <p>вызывая system.exit ()</p> </li> <li> <p>если программа переходит в бесконечный цикл.</p> </li> </ol>

<p>это действительно так в любом языке ... finally всегда будет выполняться перед оператором return, независимо от того, где этот возврат находится в теле метода. если бы это было не так, блок finally не имел бы большого значения.</p>

<p>добавление к <a href="https://stackoverflow.com/a/296053/4298200">ответ @ vibhash</a> , поскольку никакой другой ответ не объясняет, что происходит в случае изменяемого объекта, подобного приведенному ниже.</p><pre><code>public static void main(string[] args) { system.out.println(test().tostring()); } public static stringbuffer test() { stringbuffer s = new stringbuffer(); try { s.append("sb"); return s; } finally { s.append("updated "); } } </code></pre><p>будет выходной</p><blockquote> <pre><code>sbupdated </code></pre></blockquote>

<p>да, это написано <a href="https://docs.oracle.com/javase/tutorial/essential/exceptions/finally.html">здесь</a> </p><blockquote> <p>если jvm завершает работу во время выполнения кода try или catch, блок finally может не выполняться. аналогично, если поток, выполняющий код try или catch, прерывается или уничтожается, блок finally может не выполняться, даже если приложение в целом продолжается.</p> </blockquote>

<p>в дополнение к пункту о возвращении в окончательной замене возврата в блоке try, то же самое относится и к исключению. блок finally, который генерирует исключение, заменит возврат или исключение, выброшенное из блока try.</p>

<h1>не всегда</h1><p>спецификация языка java описывает, как блоки try-catch-finally и try-catch работают в <a href="https://docs.oracle.com/javase/specs/jls/se7/html/jls-14.html#jls-14.20.2">14.20.2</a> <br> ни в каком месте это не указывает, что блок finally всегда выполняется. но для всех случаев, в которых блоки try-catch-finally и try-finally завершаются, он указывает, что перед выполнением, наконец, должен быть выполнен finally.</p><pre><code>try { code inside the try block } finally { fin code inside finally block } next code executed after the try-finally block (may be in a different method). </code></pre><p>jls не гарантирует, что <strong>fin</strong> будет выполнено после <strong>кода</strong>. jls гарантирует, что если <strong>код</strong> и <strong>следующий</strong> выполнены тогда <strong>fin</strong> всегда будет выполняться после <strong>кода</strong> и до <strong>следующий</strong>.</p><p>почему jls не гарантирует, что блок finally всегда выполняется после блока try? потому что это невозможно. маловероятно, но возможно, что jvm будет прервана (kill, crash, power off) сразу после завершения блока try, но перед выполнением блока finally. jls ничего не может сделать, чтобы избежать этого.</p><p>таким образом, любое программное обеспечение, для которого его правильное поведение зависит от блоков finally, всегда выполняющихся после того, как завершены их блоки try.</p><p>возвраты в блоке try не имеют отношения к этой проблеме. если выполнение достигает кода после try-catch-finally, гарантируется, что блок finally будет выполнен до, с возвратами или без них внутри блока try.</p>

<p>блок finally не будет вызываться после возврата в паре уникальных сценариев: если сначала вызывается system.exit () или происходит сбой jvm.</p><p>позвольте мне попытаться ответить на ваш вопрос как можно проще.</p><p><strong> правило 1 </strong>: блок finally всегда выполняется (хотя есть исключения из него. но давайте придерживаться этого некоторое время.)</p><p><strong> правило 2 </strong>: операторы в блоке finally запускаются, когда управление покидает блок try или catch. передача управления может происходить в результате нормального выполнения , выполнения оператора break, continue, goto или return или распространения исключения.</p><p>в частности, в случае оператора возврата (поскольку он имеет подпись), элемент управления должен покинуть вызывающий метод, и, следовательно, вызывает блок finally соответствующей структуры try-finally. оператор return выполняется после блока finally.</p><p>в случае, если в блоке finally есть оператор return, он определенно переопределит ожидающий в блоке try, поскольку очищает стек вызовов.</p><p>вы можете найти более подробное объяснение здесь: <a href="http://msdn.microsoft.com/en-us/">http://msdn.microsoft.com/en-us/</a> .... концепция в основном одинакова на всех языках высокого уровня.</p>

<ol> <li>наконец, блок всегда исполняется. если и до тех пор, пока <strong>system.exit ()</strong> оператор не существует (первый оператор в блоке finally).</li> <li>если <strong>system.exit ()</strong> является первым оператором, то блок finally не будет выполнен, и управление выйдет из блока finally. всякий раз, когда оператор system.exit () попадает в блок finally, пока этот оператор не завершит выполнение блока, а когда появится system.exit (), управляющая сила полностью выйдет из блока finally.</li> </ol>

<p>то же самое со следующим кодом:</p><pre><code>static int f() { while (true) { try { return 1; } finally { break; } } return 2; } </code></pre><p>f вернет 2!</p>

<p>потому что финал всегда будет вызван в любых ваших случаях. у вас нет исключения, оно все еще вызывается, ловите исключение, оно все еще вызывается</p>

<p>да, он всегда будет вызываться, но в одной ситуации он не будет вызываться при использовании system.exit ().</p><pre><code>try{ //risky code }catch(exception e){ //exception handling code } finally(){ //it always execute but before this block if there is any statement like system.exit(0); then this block not execute. } </code></pre>

<p>блок finally всегда выполняется независимо от того, был ли обработчик исключения. если какое-либо исключение возникло до блока try, блок finally не будет выполнен.</p>

<p>если выбрасывается исключение, наконец запускается. если исключение не выдается, наконец запускается. если исключение поймано, наконец запускается. если исключение не перехвачено, наконец запускается.</p><p>только когда он не запускается, происходит выход из jvm.</p>

<p>рассмотрим это в обычном порядке выполнения (т. е. без каких-либо исключений): если метод не 'void', то он всегда явно что-то возвращает, но, наконец, всегда выполняется</p>

<p>попробуйте этот код, вы поймете <strong>код в блоке finally выполняется после оператора return</strong>.</p><pre><code>public class testtrycatchfinally { static int x = 0; public static void main(string[] args){ system.out.println(f1() ); system.out.println(f2() ); } public static int f1(){ try{ x = 1; return x; }finally{ x = 2; } } public static int f2(){ return x; } } </code></pre>

<p>я был очень смущен всеми ответами, предоставленными на разных форумах, и решил, наконец, написать код и посмотреть. выход является:</p><p><strong>наконец, будет выполнено, даже если в блоке try и catch есть return.</strong></p><pre><code>try { system.out.println("try"); return; //int i =5/0; //system.exit(0 ) ; } catch (exception e) { system.out.println("catch"); return; //int i =5/0; //system.exit(0 ) ; } finally { system.out.println("print me finally"); } </code></pre><p><strong>результат</strong></p><blockquote> <p>пытаться</p> <p>напиши мне, наконец,</p> </blockquote><ol start="2"> <li>если return заменяется на <code>system.exit(0)</code> в блоке try и catch в приведенном выше коде, и перед ним возникает исключение по любой причине.</li> </ol>

<p>кроме того, finally может быть преждевременно завершено, если исключение выдается внутри вложенного блока finally. компилятор предупредит вас, что блок finally не завершается нормально, или выдает ошибку, что у вас есть недоступный код. ошибка для недоступного кода будет показана только в том случае, если бросок не находится за условным оператором или внутри цикла.</p><pre><code>try{ }finally{ try{ }finally{ //if(somecondition) --> no error because of unreachable code throw new runtimeexception(); } int a = 5;//unreachable code } </code></pre>

<p>наконец всегда вызывается в конце</p><p>когда вы пытаетесь, он выполняет некоторый код, если что-то происходит при попытке, то catch поймает это исключение, и вы можете напечатать некоторое mssg или выдать ошибку, и, наконец, будет выполнен блок.</p><p>наконец, обычно используется при выполнении очистки, например, если вы используете сканер в java, вам, вероятно, следует закрыть сканер, так как это приводит к другим проблемам, таким как невозможность открыть какой-либо файл.</p>

<p>блок finally выполняется всегда, даже если вы поместили оператор return в блок try. блок finally будет выполнен перед оператором return.</p>