En lisant toutes les questions déjà posées dans ce forum en relation avec le sujet ci-dessus (voir le titre), je comprends parfaitement que finally
soit toujours appelé. (à l'exception de System.exit
et boucles infinies). Cependant, j'aimerais savoir si un return
est appelé dans un bloc catch, puis un autre return
est appelé à partir du bloc finally.
Par exemple:
public static void main(String[]args) {
int a = new TestClass().absorbeTheValue();
}
int absorbeTheValue() {
try {
int a = 10/0;
if (a > 0) return 4;
} catch(Exception e) {
return 45;
} finally {
return 34;
}
}
Donc ici la sortie (quand la méthode est appelée) va être 34 dans tous les cas. Cela signifie que finalement toujours toujours couru. Je pense cependant que les autres "retours" ne sont pas courus du tout. Dans de nombreux articles, j’ai trouvé le fait que, finalement, écrivez le contenu par-dessus ce qui avait déjà été écrit par le retour de la clause de capture. D'après ce que j'ai compris, dès que la valeur de retour dans la clause catch est sur le point d'être évaluée, le flux de contrôle passe à la clause finally qui, à son tour, comporte un autre retour. Cette fois, le retour sera évalué sans passer le contrôle à la clause catch. . De cette façon, le seul return
appelé au moment de l'exécution sera le retour final. Êtes-vous d'accord avec cela?
Un return
dans finally
ne renvoie pas le contrôle au programme mais renvoie la valeur et termine la méthode. Pouvons-nous le dire?
Si le return
du bloc try
est atteint, il transfère le contrôle au bloc finally
et la fonction retourne normalement (pas une projection).
Si une exception se produit mais que le code atteint un return
à partir du bloc catch
, le contrôle est transféré au bloc finally
et la fonction retourne finalement normalement (pas une projection). .
Dans votre exemple, vous avez return
dans finally
, et donc, peu importe ce qui se passe, la fonction retournera 34
, parce que finally
a le dernier mot (si vous voulez).
Bien que cela ne soit pas couvert dans votre exemple, cela serait vrai même si vous n'aviez pas catch
et si une exception était levée dans le bloc try
et not capturé . En faisant un return
à partir du bloc finally
, vous supprimez entièrement l'exception. Considérer:
public class FinallyReturn {
public static final void main(String[] args) {
System.out.println(foo(args));
}
private static int foo(String[] args) {
try {
int n = Integer.parseInt(args[0]);
return n;
}
finally {
return 42;
}
}
}
Si vous exécutez cela sans fournir d'arguments:
$ Java FinallyReturn
... le code dans foo
jette un ArrayIndexOutOfBoundsException
. Mais comme le bloc finally
effectue un return
, cette exception est supprimée.
C'est l'une des raisons pour lesquelles il est préférable d'éviter d'utiliser return
dans finally
.
Voici un code qui montre comment cela fonctionne.
class Test
{
public static void main(String args[])
{
System.out.println(Test.test());
}
public static String test()
{
try {
System.out.println("try");
throw new Exception();
} catch(Exception e) {
System.out.println("catch");
return "return";
} finally {
System.out.println("finally");
return "return in finally";
}
}
}
Le résultat est:
try
catch
finally
return in finally