In diesem Artikel geht es um die Analyse der Ausführungssequenz (Codebeispiele) in Java. Ich hoffe, dass er für Freunde hilfreich ist.
Wir alle kennen die Ausführungsmerkmale von „final“
1. Unabhängig davon, ob eine Ausnahme vorliegt, wird der Code im „finally“-Block ausgeführt
2 ist return in try und Catch , wird schließlich noch ausgeführt.
Dann stellt sich die Frage: Wie lautet die Ausführungsreihenfolge?
Eine einfache Testklasse und dekompilierter Bytecode:
public class Test { publicstatic void main(String[] args) { System.out.println(test()); } publicstatic int test() { try{ System.out.println("Codesin try block."); return0; }catch (Exception e) { System.out.println("Codesin catch block."); return100; }finally { System.err.println("Codesin finally block."); } } } /* public static int test(); Code: 0: getstatic #2 // Fieldjava/lang/System.out:Ljava/io/PrintStream; 3: ldc #5 // String Codes in try block. 5: invokevirtual #6 // Method java/io/PrintStream.println:(Ljava/lang/String;)V 8: iconst_0 9: istore_0 10: getstatic #7 // Field java/lang/System.err:Ljava/io/PrintStream; 13: ldc #8 // String Codes in finallyblock. 15: invokevirtual #6 // Method java/io/PrintStream.println:(Ljava/lang/String;)V 18: iload_0 19: ireturn 20: astore_0 21: getstatic #2 // Fieldjava/lang/System.out:Ljava/io/PrintStream; 24: ldc #10 // String Codes in catchblock. 26: invokevirtual #6 // Method java/io/PrintStream.println:(Ljava/lang/String;)V 29: bipush 100 31: istore_1 32: getstatic #7 // Fieldjava/lang/System.err:Ljava/io/PrintStream; 35: ldc #8 // String Codes in finallyblock. 37: invokevirtual #6 // Method java/io/PrintStream.println:(Ljava/lang/String;)V 40: iload_1 41: ireturn 42: astore_2 43: getstatic #7 // Fieldjava/lang/System.err:Ljava/io/PrintStream; 46: ldc #8 // String Codes in finallyblock. 48: invokevirtual #6 // Method java/io/PrintStream.println:(Ljava/lang/String;)V 51: aload_2 52: athrow */
Sie können den Code, den wir geschrieben haben, mit dem kompilierten Bytecode vergleichen:
Ich habe ihn gefunden dass die virtuelle Maschine eine Menge Dinge für uns erledigt hat. Sie hat den Anweisungsblock „finally“ zwischen den Anweisungen „try“, „catch“ und „return“ eingefügt. Aus diesem Grund wird „final“ unabhängig davon ausgeführt, ob eine Ausnahme vorliegt oder nicht, ob sie zurückgegeben wird oder nicht. Da „final“ ausgeführt wird, wird auch alles zurückgegeben, was „finally“ zurückgibt. Da alle Rückgaben vor „finally“ ungültig sind, was bedeutet „return“? Daher dürfen „final“-Blöcke in der Praxis nicht zurückgegeben werden. Der Eclipse-Compiler gibt eine Warnung aus: „finallyblock“ wird nicht normal abgeschlossen.
Testcode für mehrere Situationen
try{ return; }catch(){} Finally{} return;
Testcode:
1. Basisdatentyp
public static int test1(){ int a = 10; try{ a = 20; return a; }catch(Exception e){ //other codes. }finally{ a += 5; //other codes. } return a; }//最终返回值为20
2. Der Referenzdatentyp ändert den Wert des Referenzobjekts
public static StringBuffer test2(){ StringBuffer sb = new StringBuffer("abc"); try{ return sb; }catch(Exception e){ //other codes. }finally{ sb.append("DEF"); //other codes. } return sb; }//最终返回中内容为abcDEF
Beim Test dieser Situation kann festgestellt werden, dass, wenn ein return-Anweisung vor final, egal welche Änderungen an der Rückgabevariablen vorgenommen werden, die Variable selbst ändert sich beispielsweise nicht der Rückgabewert. Die Anweisung in „final“ wird jedoch ausgeführt, sodass der Inhalt des Objekts, auf das die Referenztypvariable in „final“ zeigt, geändert werden kann und die Änderung wirksam ist. Diese Situation kann folgendermaßen verstanden werden: Wenn die virtuelle Maschine auf eine Rückgabeanweisung trifft, baut sie ein Haus für den Rückgabewert. Kann das Haus nach Belieben abgerissen werden? kann nicht. Aber die Menschen im Haus können sich ändern. Die Variablen der Basisdatentypen und Referenztypen selbst sind Häuser, und der Inhalt der Objekte, auf die Referenztypvariablen verweisen, sind die Personen im Haus.
Es gibt so einen kleinen Test:
public static StringBuffer test3(){ StringBuffer sb = new StringBuffer("abc"); try{ return sb; }catch(Exception e){ //other codes. }finally{ sb = new StringBuffer("DEF"); //other codes. } return sb; }//最终返回值中的内容为abc
1.1 Was ist der Rückgabewert, wenn es im Try-Block keine Ausnahme gibt?
1.2 Was ist der Rückgabewert, wenn im Try-Block eine ArithmeticException vorliegt?
1.3 Was ist der Rückgabewert, wenn es andere Ausnahmen im Try-Block gibt?
Antwort: Alle sind 30. Der Grund dafür ist, dass der JVM nach der Ausführung des Codes vor der Rückgabe im Try-Block den Code in den Final-Block zwischen den Returns einfügt. Der Final-Block enthält Return, sodass er zurückkehrt direkt. .
Verwandte Empfehlungen:
Ausführungsreihenfolge von Try-, Final- und Return-Anweisungen in Java
Beispiele für Codeblöcke in Java Ausführungsreihenfolge
Das obige ist der detaillierte Inhalt vonAnalyse der Ausführungsreihenfolge von „final' und „return' in Java (Codebeispiel). Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!