Всегда ли выполняется блок finally в Java? - PullRequest
2172 голосов
/ 15 сентября 2008

Учитывая этот код, могу ли я быть абсолютно уверенным , что блок finally всегда выполняется, независимо от того, чем является something()?

try {  
    something();  
    return success;  
}  
catch (Exception e) {   
    return failure;  
}  
finally {  
    System.out.println("I don't know if this will get printed out");
}

Ответы [ 46 ]

18 голосов
/ 15 сентября 2008

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

17 голосов
/ 14 июля 2013

Нет, не всегда одним исключением является случай // System.exit (0); перед тем как блок finally не позволяет выполнить finally.

  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");
        }
    }
}
17 голосов
/ 15 сентября 2008

Блок finally всегда выполняется, если не происходит аварийного завершения программы, вызванного сбоем JVM или вызовом System.exit(0).

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

12 голосов
/ 13 мая 2010

Наконец, всегда запускается, и в этом весь смысл, просто потому, что он появляется в коде после возврата, не означает, что это так. Среда выполнения Java отвечает за запуск этого кода при выходе из блока try.

Например, если у вас есть следующее:

int foo() { 
    try {
        return 42;
    }
    finally {
        System.out.println("done");
    }
}

Среда выполнения сгенерирует что-то вроде этого:

int foo() {
    int ret = 42;
    System.out.println("done");
    return 42;
}

Если выброшено неперехваченное исключение, блок finally будет запущен, и исключение продолжит распространяться.

10 голосов
/ 25 мая 2010

Это потому, что вы присвоили значение i как 12, но не вернули значение i в функцию. Правильный код выглядит следующим образом:

public static int test() {
    int i = 0;
    try {
        return i;
    } finally {
        i = 12;
        System.out.println("finally trumps return.");
        return i;
    }
}
9 голосов
/ 13 мая 2010

Поскольку блок finally всегда будет вызываться, пока вы не вызовете System.exit() (или поток не завершится).

9 голосов
/ 13 августа 2016

Ответ прост ДА .

ВХОД:

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");
}

ВЫВОД:

catch
finally
8 голосов
/ 15 сентября 2008

Да, он будет вызван. В этом весь смысл ключевого слова finally. Если выпрыгивание из блока try / catch может просто пропустить блок finally, это то же самое, что поместить System.out.println вне try / catch.

8 голосов
/ 14 октября 2014

Кратко, в официальной документации Java (нажмите здесь ) написано, что -

Если JVM завершает работу во время выполнения кода try или catch, тогда блок finally может не выполняться. Аналогично, если поток выполняется код try или catch прерывается или уничтожается, блок finally может не выполняется, даже если приложение в целом продолжается.

8 голосов
/ 02 декабря 2014

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

...