Heim >Java >javaLernprogramm >Einige Hinweise zur Verwendung der Java-finally-Anweisung
Es gibt viele Leute im Internet, die darüber diskutieren, ob die final-Anweisung im try...catch...finally-Block des Ausnahmeabfangmechanismus in Java definitiv ausgeführt wird? Viele Leute sagen nein, natürlich ist ihre Antwort richtig. Nach meinen Experimenten gibt es mindestens zwei Situationen, in denen die final-Anweisung nicht ausgeführt wird:
(1) Die try-Anweisung wird nicht ausgeführt, wie zum Beispiel It kehrt vor der try-Anweisung zurück, sodass die final-Anweisung nicht ausgeführt wird. Dies zeigt auch, dass die notwendige, aber nicht ausreichende Bedingung für die Ausführung der final-Anweisung ist: Die entsprechende try-Anweisung muss ausgeführt werden.
(2) Es gibt eine Anweisung wie System.exit(0); im try-Block wird die JVM beendet. Natürlich wird die final-Anweisung nicht ausgeführt.
Natürlich diskutieren viele Leute über die Beziehung zwischen der Ausführung der „Finally“-Anweisung und der Rückkehr, was ziemlich verwirrend ist. Ich frage mich, ob die „final“-Anweisung vor oder nach der Rückkehr des Versuchs ausgeführt wird. Ich bin auch verwirrt, was sie gesagt haben. Ich denke, es sollte so sein: Die „final“-Anweisung wird ausgeführt, nachdem die „try return“-Anweisung ausgeführt wurde und bevor die „return“-Anweisung zurückgegeben wird. Diese Aussage ist etwas widersprüchlich. Im Folgenden gebe ich einige Ergebnisse und Beispiele meiner eigenen Experimente. Wenn Sie Fragen haben, können Sie diese gerne stellen.
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; } }
Das Laufergebnis ist:
try block finally block b>25, b = 100 100
gibt an, dass die Return-Anweisung vor der Ausführung der Final-Anweisung ausgeführt wurde. Sie kehrt jedoch nicht direkt zurück, sondern wartet auf die Ausführung der Final-Anweisung, bevor das Ergebnis zurückgegeben wird .
Wenn Sie der Meinung sind, dass dieses Beispiel nicht ausreicht, um die Situation zu erklären, finden Sie hier ein weiteres Beispiel, um die Schlussfolgerung zu untermauern:
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"; } }
Das laufende Ergebnis ist:
try block return statement finally block after return
Es bedeutet, dass die Return-Anweisung in try wird zuerst ausgeführt, aber es wird nicht sofort zurückgegeben.
Sie denken vielleicht: Wenn es eine return-Anweisung gibt, kann try nicht direkt zurückgegeben werden zurückgegeben werden? Siehe unten.
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; } }
Das Laufergebnis ist:
try block finally block b>25, b = 100 200
Dies bedeutet, dass die Rückgabe direkt erfolgt, unabhängig davon, ob eine Rückgabeanweisung in try vorhanden ist. Nach dem Hinzufügen von return to muss darauf geachtet werden endlich, endlich Die äußere Rückgabe b wird zu einer nicht erreichbaren Anweisung, das heißt, sie kann nie ausgeführt werden, daher muss sie auskommentiert werden, sonst meldet der Compiler einen Fehler.
Hier denken Sie vielleicht auch: Wenn es in „finally“ keine Return-Anweisung gibt, aber der Wert von b geändert wird, gibt die Rückgabe in „try“ dann den geänderten Wert oder den ursprünglichen Wert zurück? Siehe unten.
Testfall 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; } }
Das Laufergebnis ist:
try block finally block b>25, b = 100 100
Testfall 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!
Das obige ist der detaillierte Inhalt vonEinige Hinweise zur Verwendung der Java-finally-Anweisung. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!