De nombreuses personnes sur Internet se demandent si l'instruction final du bloc try...catch...finally du mécanisme de capture d'exceptions en Java sera définitivement exécutée ? Beaucoup de gens disent non, bien sûr leur réponse est correcte. Après mes expériences, il y a au moins deux situations dans lesquelles l'instruction final ne sera pas exécutée :
(1) L'instruction try n'est pas exécutée, comme It. renvoie avant l'instruction try, de sorte que l'instruction final ne soit pas exécutée. Cela montre également que la condition nécessaire mais pas suffisante pour que l'instruction finale soit exécutée est : l'instruction try correspondante doit être exécutée.
(2) Il y a une instruction comme System.exit(0); dans le bloc try System.exit(0); bien sûr, l'instruction finale ne sera pas exécutée.
Bien sûr, beaucoup de gens discutent de la relation entre l'exécution de l'instruction Final et le retour, ce qui est assez déroutant. Je me demande si l'instruction final est exécutée avant ou après le retour du try ? Je suis également confus. Je ne pense pas que ce qu'ils ont dit soit correct. Je pense que cela devrait l'être : l'instruction final est exécutée après l'exécution de l'instruction try return et avant le retour du retour. Cette affirmation est un peu contradictoire. Peut-être que mon expression n'est pas assez claire. Ci-dessous, je vais donner quelques résultats et exemples de mes propres expériences pour l'étayer. Si vous avez des questions, n'hésitez pas à les poser.
public class FinallyTest1 { public static void main(String[] args) { System.out.println(test1()); } public static int test1() { int b = 20; try { System.out.println("try block"); return b += 80; } catch (Exception e) { System.out.println("catch block"); } finally { System.out.println("finally block"); if (b > 25) { System.out.println("b>25, b = " + b); } } return b; } }
Le résultat en cours d'exécution est :
try block finally block b>25, b = 100 100
indique que l'instruction return a été exécutée avant d'exécuter l'instruction finale. Cependant, elle ne renvoie pas directement, mais attend que l'instruction finale soit exécutée avant de renvoyer le résultat. .
Si vous estimez que cet exemple ne suffit pas à expliquer la situation, voici un autre exemple pour renforcer la conclusion :
public class FinallyTest1 { public static void main(String[] args) { System.out.println(test11()); } public static String test11() { try { System.out.println("try block"); return test12(); } finally { System.out.println("finally block"); } } public static String test12() { System.out.println("return statement"); return "after return"; } }
Le résultat courant est :
try block return statement finally block after return
Cela signifie que la déclaration de retour in try est exécuté en premier Mais il ne revient pas immédiatement. Attendez que l'exécution definally soit terminée
Vous pensez peut-être ici : s'il y a une instruction return infinally, est-ce qu'elle renvoie directement ? ne peut pas être retourné ? Voir ci-dessous.
public class FinallyTest2 { public static void main(String[] args) { System.out.println(test2()); } public static int test2() { int b = 20; try { System.out.println("try block"); return b += 80; } catch (Exception e) { System.out.println("catch block"); } finally { System.out.println("finally block"); if (b > 25) { System.out.println("b>25, b = " + b); } return 200; } // return b; } }
Le résultat en cours d'exécution est :
try block finally block b>25, b = 100 200
Cela signifie que le return in revient finalement directement, qu'il y ait ou non une instruction return dans try. Il y a un petit détail auquel faire attention ici après avoir ajouté return. à enfin, enfin Le retour externe b devient une instruction inaccessible, c'est-à-dire qu'elle ne peut jamais être exécutée, elle doit donc être commentée sinon le compilateur signalera une erreur.
Ici, vous pouvez aussi penser : s'il n'y a pas d'instruction return dans final, mais que la valeur de b est modifiée, alors le retour dans try renvoie-t-il la valeur modifiée ou la valeur d'origine ? Voir ci-dessous.
Cas de test 1 :
public class FinallyTest3 { public static void main(String[] args) { System.out.println(test3()); } public static int test3() { int b = 20; try { System.out.println("try block"); return b += 80; } catch (Exception e) { System.out.println("catch block"); } finally { System.out.println("finally block"); if (b > 25) { System.out.println("b>25, b = " + b); } b = 150; } return 2000; } }
Le résultat en cours d'exécution est :
try block finally block b>25, b = 100 100
Cas de test 2 :
import java.util.*; public class FinallyTest6 { public static void main(String[] args) { System.out.println(getMap().get("KEY").toString()); } public static Map<string> getMap() { Map<string> map = new HashMap<string>(); map.put("KEY", "INIT"); try { map.put("KEY", "TRY"); return map; } catch (Exception e) { map.put("KEY", "CATCH"); } finally { map.put("KEY", "FINALLY"); map = null; } return map; } }</string></string></string>
运行结果是:
FINALLY
为什么测试用例1中finally里的b = 150;并没有起到作用而测试用例2中finally的map.put("KEY", "FINALLY");起了作用而map = null;却没起作用呢?这就是Java到底是传值还是传址的问题了,具体请看精选30道Java笔试题解答,里面有详细的解答,简单来说就是:Java中只有传值没有传址,这也是为什么map = null这句不起作用。这同时也说明了返回语句是try中的return语句而不是 finally外面的return b;这句,不相信的话可以试下,将return b;改为return 294,对原来的结果没有一点影响。
这里大家可能又要想:是不是每次返回的一定是try中的return语句呢?那么finally外的return b不是一点作用没吗?请看下面。
public class FinallyTest4 { public static void main(String[] args) { System.out.println(test4()); } public static int test4() { int b = 20; try { System.out.println("try block"); b = b / 0; return b += 80; } catch (Exception e) { b += 15; System.out.println("catch block"); } finally { System.out.println("finally block"); if (b > 25) { System.out.println("b>25, b = " + b); } b += 50; } return 204; } }
运行结果是:
try block catch block finally block b>25, b = 35 85
这里大家可能又有疑问:如果catch中有return语句呢?当然只有在异常的情况下才有可能会执行,那么是在finally之前就返回吗?看下面。
public class FinallyTest5 { public static void main(String[] args) { System.out.println(test5()); } public static int test5() { int b = 20; try { System.out.println("try block"); b = b /0; return b += 80; } catch (Exception e) { System.out.println("catch block"); return b += 15; } finally { System.out.println("finally block"); if (b > 25) { System.out.println("b>25, b = " + b); } b += 50; } //return b; } }
运行结果如下:
try block catch block finally block b>25, b = 35 35
说明了发生异常后,catch中的return语句先执行,确定了返回值后再去执行finally块,执行完了catch再返回,finally里对b的改变对返回值无影响,原因同前面一样,也就是说情况与try中的return语句执行完全一样。
最后总结:finally块的语句在try或catch中的return语句执行之后返回之前执行且finally里的修改语句可能影响也可能不影响try或catch中 return已经确定的返回值,若finally里也有return语句则覆盖try或catch中的return语句直接返回。
学习Java的同学注意了!!!
学习过程中遇到什么问题或者想获取学习资源的话,欢迎加入Java学习交流群:159610322 我们一起学Java!
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!