it-swarm-fr.com

Est-ce qu'un bloc finally est toujours exécuté en Java?

Compte tenu de ce code, puis-je être absolument sûr que le bloc finally est toujours exécuté, peu importe ce que something() est?

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

Oui, finally sera appelé après l'exécution des blocs de code try ou catch.

Les seuls moments où finally ne seront pas appelés sont les suivants:

  1. Si vous appelez System.exit()
  2. Si la JVM plante en premier
  3. Si la machine virtuelle Java atteint une boucle infinie (ou une autre instruction non terminable et non interruptible) dans le bloc try ou catch
  4. Si le système d'exploitation met fin de force au processus JVM; par exemple, kill -9 <pid> sous UNIX
  5. Si le système hôte meurt; par exemple, panne de courant, erreur matérielle, panique du système d'exploitation, etc.
  6. Si le bloc finally est sur le point d'être exécuté par un thread de démon et que tous les autres threads non-démons se terminent avant que finally ne soit appelé
2491
jodonnell

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

Sortie:

finally trumps return. 
0
520
Kevin

En outre, bien que ce soit une mauvaise pratique, s'il existe une instruction return dans le bloc finally, elle aura priorité sur tout autre retour du bloc normal. En d'autres termes, le bloc suivant renverrait false:

try { return true; } finally { return false; }

Même chose avec les exceptions de lancement du bloc finally.

370
MooBob42

Voici les mots officiels de la spécification de langage Java.

14.20.2. Exécution d'essayer-enfin et d'essayer-attraper-finalement

Une instruction try avec un bloc finally est exécutée en exécutant d'abord le bloc try. Ensuite, il y a un choix:

  • Si l'exécution du bloc try se termine normalement, [...]
  • Si l'exécution du bloc try se termine brusquement à cause d'un throw d'une valeur V, [...]
  • Si l'exécution du bloc try s'achève abruptement pour toute autre raison R, le bloc finally est réalisé. Ensuite, il y a un choix:
    • Si le bloc finally se termine normalement, l'instruction try se termine brusquement pour une raison R.
    • Si le bloc finally s'achève abruptement pour une raison S, l'instruction try s'achève abruptement pour une raison S ( et raison R est ignoré ).

La spécification de return rend cela explicite:

JLS 14.17 The return statement

ReturnStatement:
     return Expression(opt) ;

Une instruction return sans Expression tente de transférer le contrôle à l'appelant de la méthode ou du constructeur qui le contient.

Une instruction return avec une Expression tente de transférer le contrôle à l'appelant de la méthode qui le contient; la valeur de Expression devient la valeur de l'appel de la méthode.

Les descriptions précédentes disent " tente de transférer le contrôle " plutôt que simplement " transfère le contrôle "parce que s'il existe des instructions try dans la méthode ou le constructeur dont les blocs try contiennent l'instruction return, les clauses finally de ces instructions try seront exécutées, dans l'ordre, du plus interne au plus externe, avant que le contrôle ne soit transféré à l'appelant de la méthode ou du constructeur. L'achèvement brutal d'une clause finally peut perturber le transfert du contrôle initié par une instruction return.

251

En plus des autres réponses, il est important de souligner que 'finally' a le droit de remplacer toute valeur d'exception/renvoyée par le bloc try..catch. Par exemple, le code suivant renvoie 12:

public static int getMonthsInYear() {
    try {
        return 10;
    }
    finally {
        return 12;
    }
}

De même, la méthode suivante ne lève pas d'exception:

public static int getMonthsInYear() {
    try {
        throw new RuntimeException();
    }
    finally {
        return 12;
    }
}

Alors que la méthode suivante le jette:

public static int getMonthsInYear() {
    try {
        return 12;          
    }
    finally {
        throw new RuntimeException();
    }
}
151
Eyal Schneider

J'ai essayé l'exemple ci-dessus avec une légère modification-

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

Le code ci-dessus renvoie:

l'emporte enfin sur le retour.
2

En effet, lorsque return i; est exécuté, i a la valeur 2. Après cela, le bloc finally est exécuté, où 12 est affecté à i, puis System.out out. est exécuté.

Après avoir exécuté le bloc finally, le bloc try renvoie 2 au lieu de 12, car cette instruction de retour n'est pas exécutée à nouveau.

Si vous déboguez ce code dans Eclipse, vous aurez alors le sentiment qu'après l'exécution de System.out de finally, l'instruction return du bloc try est exécutée à nouveau. Mais ce n'est pas le cas. Il retourne simplement la valeur 2.

111
vibhash

Voici une élaboration de réponse de Kevin . Il est important de savoir que l'expression à renvoyer est évaluée avant finally, même si elle est renvoyée après.

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

Sortie:

X
finally trumps return... sort of
0
101
WoodenKitty

C'est l'idée même d'un blocage final. Cela vous permet de vous assurer que vous effectuez des nettoyages qui pourraient sinon être ignorés, entre autres choses, bien sûr.

Enfin est appelé peu importe ce qui se passe dans le bloc try ( à moins que vous appeliez System.exit(int) ou le Java La machine virtuelle est mise hors service pour une autre raison).

53
Chris Cooper

Une façon logique de penser à cela est:

  1. Le code placé dans un bloc finally doit être exécuté quoi qu'il arrive dans le bloc try
  2. Donc, si le code du bloc try tente de renvoyer une valeur ou de lever une exception, l'élément est placé 'sur l'étagère' jusqu'à ce que le bloc finally puisse être exécuté.
  3. Parce que le code dans le bloc finally a (par définition) une priorité élevée, il peut renvoyer ou lancer ce qu’il veut. Dans ce cas, tout ce qui reste "sur l'étagère" est jeté.
  4. La seule exception à cette règle est si le VM est complètement arrêté pendant le bloc try, par exemple. par 'System.exit'
39
Garth Gilmour

enfin, l'exécution est toujours exécutée sauf en cas de fin anormale du programme (par exemple, en appelant System.exit (0) ..). alors, votre sysout sera imprimé

19
shyam

De plus, un retour à la campagne éliminera finalement toute exception. http://jamesjava.blogspot.com/2006/03/dont-return-in-finally-clause.html

19

Le bloc finally est toujours exécuté sauf en cas de fin anormale du programme, résultant d'un crash de la machine virtuelle Java ou d'un appel à System.exit(0).

De plus, toute valeur renvoyée à l'intérieur du bloc finally sera prioritaire sur la valeur renvoyée avant l'exécution du bloc finally. Veillez donc à vérifier tous les points de sortie lors de l'utilisation de try finally.

18
user9189

Non, un cas d'exception n'est pas toujours // System.exit (0); avant que le bloc finally empêche enfin d'être exécuté.

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

Finalement, c'est toujours le but, simplement parce que cela apparaît dans le code après la déclaration ne signifie pas que c'est ainsi qu'il est mis en œuvre. Le runtime Java a la responsabilité d'exécuter ce code lors de la sortie du bloc try.

Par exemple, si vous avez ce qui suit:

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

Le runtime va générer quelque chose comme ceci:

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

Si une exception non capturée est levée, le bloc finally sera exécuté et l'exception continuera à se propager.

13
Motti

Cela est dû au fait que vous avez affecté la valeur de i à 12, mais que vous n’avez pas renvoyé la valeur de i à la fonction. Le code correct est le suivant:

public static int test() {
    int i = 0;
    try {
        return i;
    } finally {
        i = 12;
        System.out.println("finally trumps return.");
        return i;
    }
}
11
Wasim

Car un bloc finally sera toujours appelé à moins que vous n'appeliez System.exit() (ou que le thread se bloque).

10
Jay Riggs

La réponse est simple OUI.

INPUT:

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

OUTPUT:

catch
finally
10
Meet

Oui, il sera appelé. C'est tout l'intérêt d'avoir un mot-clé enfin. Si sauter du bloc try/catch pouvait juste ignorer le dernier bloc, c’était la même chose que de placer le System.out.println en dehors du try/catch.

9
Mendelt

Oui, enfin le bloc est toujours exécuté. La plupart des développeurs utilisent ce blocage pour fermer la connexion à la base de données, l’objet de jeu de résultats, l’objet instruction et également l’utiliser dans le Java hibernate pour annuler la transaction.

9
Gautam Viradiya

En résumé, dans la documentation officielle Java (Cliquez ici ), il est écrit que -

Si la machine virtuelle Java se ferme pendant l'exécution du code try ou catch, le bloc finally peut ne pas s'exécuter. De même, si le thread qui exécute le code try ou catch est interrompu ou tué, le bloc finally peut ne pas s'exécuter même si l'application continue dans son ensemble.

9
bikz05

Oui, il sera. Le seul cas où cela ne se produira pas est le blocage ou la fermeture de la machine virtuelle Java

8
abhig

Oui, il sera. Peu importe ce qui se passe dans votre bloc try ou catch, sauf indication contraire de System.exit () ou de JVM bloquée. s'il y a une instruction de retour dans le (s) bloc (s), elle sera finalement exécutée avant cette instruction de retour.

8
Karthikeyan

Considérez le programme suivant:

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

À partir de Java 1.8.162, le bloc de code ci-dessus donne la sortie suivante:

-abc-
---AGAIN---
-abc-xyz-abc-
---PRINT THE RESULT---
-abc-xyz-abc-xyz

cela signifie que l'utilisation de finally pour libérer des objets est une bonne pratique à l'instar du code suivant:

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.
    }
}
8
Samim

Ajouter à réponse de @ vibhash car aucune autre réponse n'explique ce qui se passe dans le cas d'un objet mutable comme celui ci-dessous.

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

Sortie

sbupdated 
8
Pradeep Kumaresan

finally va s'exécuter et c'est sûr.

finally ne sera pas exécuté dans les cas suivants:

cas 1 :

Lorsque vous exécutez System.exit().

cas 2:

Lorsque votre machine virtuelle/thread se bloque.

cas 3:

Lorsque votre exécution est arrêtée entre les deux manuellement.

7
Utkash Bhatt

En plus du point sur le retour dans le remplacement final d'un retour dans le bloc try, il en va de même pour une exception. Un bloc finally qui lève une exception remplacera un retour ou une exception levée depuis le bloc try.

7
Alex Miller

C’est vrai dans toutes les langues ... enfin, il sera toujours exécuté avant une instruction return, quel que soit l’emplacement de ce retour dans le corps de la méthode. Si ce n'était pas le cas, le blocage final n'aurait pas beaucoup de sens.

7
Scott Dorman

J'ai essayé ceci, il est simple thread.

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

Le fil principal sera sur l'état d'attente pour toujours, donc finalement ne sera jamais appelé,

donc la sortie de la console n'imprimera pas la chaîne: after wait() ou finally

Convenu avec @Stephen C, l’exemple ci-dessus est l’une des 3èmes mention de cas ici :

Ajout de nouvelles possibilités de boucle infinies dans le code suivant:

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

Cas 2: Si la machine virtuelle Java plante en premier

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

Ref: Comment écrasez-vous une machine virtuelle?

Cas 6: Si le bloc finally est exécuté par le thread de démon et que tous les autres threads non-démons se terminent avant l'appel final.

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

output: Ceci n'imprime pas "finally" ce qui implique "Enfin bloc" dans "thread démon" n'a pas été exécuté

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
6
dkb

Oui, car aucune instruction de contrôle peut empêcher l'exécution de finally.

Voici un exemple de référence où tous les blocs de code seront exécutés:

| 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      |

Dans la variante ci-dessous, return x; sera ignoré. Le résultat est toujours 4:

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

Les références, bien sûr, suivent leur statut. Cet exemple retourne une référence avec value = 4:

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
    }
}
6
Dávid Horváth

Si vous ne gérez pas d'exception, avant de terminer le programme, JVM exécute enfin block. Il ne sera exécuté que si l'exécution normale du programme échoue, c'est-à-dire que le programme est arrêté pour les raisons suivantes.

  1. En provoquant une erreur fatale entraînant l'abandon du processus.

  2. Fin du programme en raison d'une mémoire corrompue.

  3. En appelant System.exit ()

  4. Si le programme passe en boucle infinie.

6

PAS TOUJOURS

La spécification de langage Java décrit le fonctionnement des blocs try-catch-finally et try-catch à 14.20.2
En aucun endroit, il ne spécifie que le bloc finally est toujours exécuté. Mais pour tous les cas dans lesquels les blocs try-catch-finally et try-finally sont terminés, il est précisé qu'avant l'achèvement, il doit être exécuté.

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).

JLS ne garantit pas que FIN est exécuté après CODE. Le JLS garantit que si CODE et SUIVANT sont exécutés alors FIN sera toujours exécuté après CODE et avant NEXT.

Pourquoi JLS ne garantit-il pas que le bloc finally est toujours exécuté après le bloc try? Parce que c'est impossible. Il est peu probable mais possible que la machine virtuelle Java soit annulée (kill, crash, power off) juste après avoir terminé le bloc try mais avant l'exécution du bloc finally. JLS ne peut rien faire pour éviter cela.

Ainsi, tous les logiciels dont le comportement correct dépend du fait que les blocs sont toujours exécutés une fois leurs blocs d’essai terminés sont bogués.

Les retours dans le bloc try n’ont aucune incidence sur ce problème. Si l'exécution atteint le code après try-catch-finally, il est garanti que le dernier bloc aura déjà été exécuté, avec ou sans retours à l'intérieur du bloc try.

6
  1. Enfin, Block est toujours exécuté. Sauf si et jusqu'à ce que System.exit (), il existe une première instruction (la première instruction du bloc finally).
  2. Si system.exit () est la première instruction, alors block ne sera pas exécuté et le contrôle sortira du bloc finally. Chaque fois que l'instruction System.exit () entre dans le bloc finally jusqu'à ce que l'instruction soit enfin exécutée et que System.exit () apparaisse, la force de contrôle sort entièrement du bloc finally.
6
Avinash Pande

try- catch- finally sont les mots clés pour utiliser le cas de traitement des exceptions.
Comme explotoire normal

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
}

Le bloc finally empêche l'exécution ...

  • Quand vous avez appelé System.exit(0);
  • Si JVM se ferme.
  • Erreurs dans la machine virtuelle Java
5

Le bloc finally ne sera pas appelé après le retour dans quelques scénarios uniques: si System.exit () est appelé en premier ou si la machine virtuelle Java se bloque.

Laissez-moi essayer de répondre à votre question de la manière la plus simple possible.

Règle 1 : le bloc finally est toujours exécuté (bien qu'il y ait des exceptions, mais restons-y pendant un moment.)

Règle 2 : les instructions du bloc finally sont exécutées lorsque le contrôle laisse un bloc try ou catch.Le transfert du contrôle peut survenir à la suite d'une exécution normale. , de l'exécution d'une pause, continue, goto ou d'une déclaration de retour, ou d'une propogation d'une exception.

Dans le cas d'une instruction return en particulier (depuis son libellé), le contrôle doit quitter la méthode appelante, et appelle donc le bloc finally de la structure try-finally correspondante. L'instruction return est exécutée après le bloc finally.

Dans le cas où il y aurait aussi une instruction return dans le bloc finally, elle remplacera certainement celle en attente dans le bloc try, car elle efface la pile d'appels.

Vous pouvez vous référer à une meilleure explication ici: http://msdn.Microsoft.com/en-us/ .... le concept est généralement identique dans toutes les langues de haut niveau.

5
Sandip Solanki

Oui, il est écrit ici

Si la machine virtuelle Java se ferme pendant l'exécution du code try ou catch, le bloc finally peut ne pas s'exécuter. De même, si le thread qui exécute le code try ou catch est interrompu ou tué, le bloc finally peut ne pas s'exécuter même si l'application continue dans son ensemble.

4
Danail Tsvetanov

Enfin, block toujours exécuter, qu’il s’agisse ou non d’une exception. Si une exception se produisait avant le bloc try, le bloc ne sera finalement pas exécuté.

4
Rohit Chugh

Si une exception est levée, finalement s'exécute. Si une exception n'est pas levée, finalement s'exécute. Si l'exception est interceptée, s'exécute enfin. Si l'exception n'est pas interceptée, s'exécute enfin.

Seul le temps pendant lequel elle ne s'exécute pas correspond à la fermeture de la machine virtuelle Java.

4
Bhushan

Essayez ce code, vous comprendrez le le code dans le bloc est enfin exécuté après la déclaration.

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;
    }
}
4
eric2323223

J'étais très confus avec toutes les réponses fournies sur différents forums et j'ai finalement décidé de coder et de voir. La sortie est:

sera finalement exécuté même s'il y a un retour dans try et catch block.

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

sortie

essayer

Imprimez-moi ENFIN

  1. Si return est remplacé par System.exit(0) dans try et attraper le bloc dans le code ci-dessus et une exception se produit avant, pour une raison quelconque.
4
milton

Idem avec le code suivant:

static int f() {
    while (true) {
        try {
            return 1;
        } finally {
            break;
        }
    }
    return 2;
}

f retournera 2!

3
dibo

Parce que la finale est toujours appelée dans tous les cas. Vous n'avez pas d'exception, il s'appelle toujours, catch exception, il s'appelle toujours

3
vodkhang

enfin, il est également possible de quitter prématurément si une exception est levée à l’intérieur d’un bloc enfin imbriqué. Le compilateur vous avertira que le bloc finally ne se termine pas normalement ou vous avertit que votre code est inaccessible. L'erreur pour le code inaccessible ne sera affichée que si le jet n'est pas derrière une instruction conditionnelle ou dans une boucle.

try{
}finally{
   try{
   }finally{
      //if(someCondition) --> no error because of unreachable code
      throw new RunTimeException();
   }
   int a = 5;//unreachable code
}
3
HopefullyHelpful

Oui, il sera toujours appelé, mais dans un cas, il n'appelle pas lorsque vous utilisez System.exit ()

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.
}
3
Akash Manngroliya

Considérez ceci dans un cours normal d'exécution (c'est-à-dire sans qu'aucune exception ne soit levée): si la méthode n'est pas 'vide', elle retourne toujours explicitement quelque chose, mais finalement, elle est toujours exécutée

3
Gala101

Enfin on appelle toujours à la fin

lorsque vous essayez, il exécute du code; si quelque chose se produit lors de l’essai, catch interceptera cette exception et vous pouvez imprimer des messages ou émettre une erreur, puis bloquer est exécuté.

Enfin, normalement utilisé lors des nettoyages, par exemple, si vous utilisez un scanner en Java, vous devez probablement le fermer car cela pose d’autres problèmes, tels que le fait de ne pas pouvoir ouvrir certains fichiers.

2
Rubin Luitel

enfin, block est toujours exécuté même si vous mettez une instruction return dans le bloc try. Le bloc finally sera exécuté avant l'instruction de retour.

2
Sabrina

Voici quelques conditions qui peuvent contourner un blocage final:

  1. Si la machine virtuelle Java se ferme pendant l'exécution du code try ou catch, le bloc finally peut ne pas s'exécuter. Plus sur tutoriel Sun
  2. Arrêt normal - cela se produit lorsque le dernier thread non démon quitte OR lorsque Runtime.exit () ( n bon blog ). Lorsqu'un thread se ferme, la machine virtuelle Java effectue un inventaire des threads en cours d'exécution. Si les seuls threads restants sont des threads démon, elle déclenche un arrêt ordonné. Lorsque la machine virtuelle Java s'arrête, tous les threads de démon restants sont abandonnés. Enfin, les blocs ne sont pas exécutés, les piles ne sont pas déroulées, la machine virtuelle Java vient de quitter. Les threads Daemon doivent être utilisés avec parcimonie. Peu d’activités de traitement peuvent être abandonnées en toute sécurité à tout moment sans nettoyage. En particulier, il est dangereux d’utiliser des threads de démon pour les tâches susceptibles d’exécuter toute sorte d’E/S. Les threads de démon sont mieux sauvegardés pour les tâches "de maintenance", tels qu'un thread d'arrière-plan qui supprime périodiquement les entrées expirées d'un cache en mémoire ( source )

Dernier exemple de thread non démon:

public class TestDaemon {
    private static Runnable runnable = new Runnable() {
        @Override
        public void run() {
            try {
                while (true) {
                    System.out.println("Is alive");
                    Thread.sleep(10);
                    // throw new RuntimeException();
                }
            } catch (Throwable t) {
                t.printStackTrace();
            } finally {
                System.out.println("This will never be executed.");
            }
        }
    };

    public static void main(String[] args) throws InterruptedException {
        Thread daemon = new Thread(runnable);
        daemon.setDaemon(true);
        daemon.start();
        Thread.sleep(100);
        // daemon.stop();
        System.out.println("Last non-daemon thread exits.");
    }
}

Sortie:

Is alive
Is alive
Is alive
Is alive
Is alive
Is alive
Is alive
Is alive
Is alive
Is alive
Last non-daemon thread exits.
Is alive
Is alive
Is alive
Is alive
Is alive
0
Mykhaylo Adamovych