Finlally виконується майже завжди.
Update, хотів би доповнити моя відповідь з приводу обробки виключень в java. Розглянемо 3 випадки, які здалися мені цікавими. Ось метод testFinally ()
В даних випадку ми зможемо побачити що блок finally відпрацьовує завжди, що й треба було довести.
Другий випадку пов'язаний з многопточностью, вірніше з тим фактом що, це правило також справедливо і для багатопоточних додатків.
Тут теж все буде правильно, тобто блок finally відпрацює. Але не для потоків демонів. Як не дивно, джава приб'є їх і не вдавитися без виконання блоків фана.
Що доводить що скрізь є винятки, навіть в винятки)
відповідь дан 22 дек '12 о 9:39
@Artemis Ви вирішили на всі питання відповісти, навіть отвеченние давно? - rasmisha 22 дек '12 о 10:27
Якщо відповідь правильна навіщо мінусувати? - Barmaley 22 дек '12 о 18:14
@Artemis, відповідати на питання - це добре. Просто, якщо на питання вже давно дан правильну відповідь (і ця відповідь прийнятий), то не варто давати ще один відповідь, особливо якщо Ваш відповідь не додає істотну інформацію. - avp 22 дек '12 о 18:54
На додаток до існуючих відповідей привожу посилання на відповідні розділи документації.
Чому finally повинен викликатися після return описано в специфікації мови Java в розділах по return і finally:
14.17. The return Statement
.
A return statement with an Expression attempts to transfer control to the invoker of the method or lambda body that contains it; the value of the Expression becomes the value of the method invocation. More precisely, execution of such a return statement first evaluates the Expression. If the evaluation of the Expression completes abruptly for some reason, then the return statement completes abruptly for that reason. If evaluation of the Expression completes normally, producing a value V, then the return statement completes abruptly, the reason being a return with value V.
14.20.2. Execution of try-finally and try-catch-finally
.
If execution of the try block completes abruptly for any other reason R, then the finally block is executed, and then there is a choice:
- If the finally block completes normally, then the try statement completes abruptly for reason R.
- If the finally block completes abruptly for reason S, then the try statement completes abruptly for reason S (and reason R is discarded).
14.17. Інструкція return
.
Інструкція return з виразом Expression намагається передати управління коду, який викликав метод або лямбда-вираз, що містить цю інструкцію; значення Expression стає значенням виклику методу. Говорячи більш строго, виконання такої інструкції return спочатку обчислює Expression. Якщо обчислення Expression завершується передчасно з деякої причини, інструкція return завершується передчасно по тій же самій причині. Якщо обчислення Expression завершується нормально, даючи значення V, то інструкція return завершується передчасно з тієї причини, що вона є поверненням значення V
14.20.2. Виконання try-finally і try-catch-finally
.
Якщо виконання блоку try завершується передчасно за деякою іншої причини R, виконується блок finally. Далі можливі наступні варіанти.
- Якщо блок finally завершується нормально, то інструкція try завершується передчасно через R.
- Якщо блок finally завершується преждевеременно S, інструкція try завершується передчасно через S (причина R ігнорується).
Якщо коротко, то виклик return - окремий випадок передчасного завершення, при цьому передчасне завершення з finally перекриває і відкидає будь-передчасне завершення в блоці try.
Якщо в блоці try буде викинуто виключення, яке не буде спіймано жодним з блоків catch (якщо вони є), то воно буде відкинуте та забуте при виклику return. або при викиданні нового виключення в finally.