java - without - try finally python




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

La réponse est simple OUI .

CONTRIBUTION:

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

SORTIE:

catch
finally

Compte tenu de ce code, puis-je être absolument sûr que le bloc finally s'exécute toujours, 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.");
}

C’est vrai dans toutes les langues ... enfin, il s’exécutera toujours 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.


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


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

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

    private static String someString() {

        try {
            sb.append("-abc-");
            return sb.toString();

        } finally {
            sb.append("xyz");
        }
    }
}

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

-abc-
---AGAIN---
-abc-xyz-abc-

Cela signifie qu'utiliser finally pour libérer des objets est une bonne pratique comme le code suivant:

private static String someString() {

    StringBuilder sb = new StringBuilder();

    try {
        sb.append("abc");
        return sb.toString();

    } finally {
        sb = null;
    }
}

De plus, bien que ce soit une mauvaise pratique, s'il y a une déclaration return dans le bloc finally, elle remplacera tout autre retour du bloc normal. C'est-à-dire que le bloc suivant renverrait false:

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

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


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

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.


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


Enfin, il est toujours exécuté sauf en cas d’arrêt anormal du programme (par exemple, en appelant System.exit (0) ..). alors, votre sysout sera imprimé


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

Finalement, c'est toujours le but, simplement parce que cela apparaît dans le code après le retour 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 s'exécutera et l'exception continuera à se propager.


Le bloc finally est toujours exécuté sauf en cas de cessation 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 remplacera 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.


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

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 la veille prolongée pour annuler la transaction.


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


Oui, il sera. Peu importe ce qui se passe dans votre bloc try ou catch, à moins que System.exit () appelé ou la machine virtuelle Java ne se bloque. s'il y a une instruction de retour dans le (s) bloc (s), elle sera finalement exécutée avant cette instruction de retour.


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


Une façon logique de penser à cela est:

  1. Le code placé dans un bloc finally doit être exécuté quoi que se passe 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 du 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 à cela est que la VM s'arrête complètement pendant le bloc try, par exemple avec 'System.exit'

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

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

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 termine normalement, [...]
  • Si l'exécution du bloc try 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 exécuté. Ensuite, il y a un choix:
    • Si le bloc finally se termine normalement, l'instruction try termine brutalement pour la raison R.
    • Si le bloc finally s'achève abruptement pour la raison S , l'instruction try s'achève abruptement pour la raison S ( et la raison R est ignorée ).

La spécification de return rend ceci explicitement:

JLS 14.17 La déclaration de retour

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 l' Expression devient la valeur de l'appel de la méthode.

Les descriptions précédentes indiquent " tentatives de transfert de contrôle " plutôt que simplement " transferts de contrôle " car s'il existe des instructions try dans la méthode ou le constructeur dont les blocs try contiennent l'instruction return , toutes les clauses finally de ces instructions try seront exécutées, dans 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. La conclusion brusque d'une clause finally peut perturber le transfert de contrôle initié par une instruction return .





try-catch-finally