Das endgültige Schlüsselwort in Java wird normalerweise mit dem Try Catch -Block verwendet. Wird verwendet, um einige Ressourcenfreigabeberationen vor dem Ende der Methode oder zu einer Ausnahme auszuführen. Kürzlich habe ich auch einige Artikel im Internet gesehen, in denen die Reihenfolge der Ausführung von Try Catch End -Keywords diskutiert wurde, und es wird angegeben, dass der endgültige Block am Ende der Methode ausgeführt wird.
Diese Ansichten glauben im Allgemeinen:
1) Das schließlich wird nach der Rückkehr nach der Programmrückgabeerklärung ausgeführt. Der Rückgabewert wird in einem temporären Bereich gespeichert. Nach der Ausführung des letzten Blocks wird der Wert des temporären Bereichs zurückgegeben.
2) Wenn der endgültige Block einen Rückgabewert gibt, ersetzt er den Wert, der im temporären Bereich des vorherigen Versuchs oder Fangblocks im Programm gespeichert ist.
Aber ist das Problem wirklich so? Lassen Sie uns sorgfältig darüber nachdenken. JVM erklärt und führt Bytecode -Anweisungen zur Laufzeit aus. Wenn es die Rückgabeerklärung ausführt, weiß er nicht, ob es danach einen endgültigen Block gibt? Was ist, wenn es keinen endgültigen Block gibt? Ob es sich um eine Bytecode -Anweisung oder eine Computeranweisung handelt, sollte klar sein. JVM ist nicht so schlau. Die gleiche Anweisung muss klar sein und enthält keine zwei Bedeutungen. Unabhängig von der Rücklaufanweisung beim Ausführen wird der Inhalt des Stapels aufgetaucht und zur Anrufmethode zurückgegeben.
Gleichzeitig können wir sehen, dass das Buch "Deep Into Java Virtual Machine" eine andere Erklärung gibt. Wenn der Java -Compiler die endgültige Klausel kompiliert, wird eine JSR -Anweisung erzeugt. Es führt dazu, dass die JVM zur Ausführung zu einem Mini -Unterroutine aufgerufen wird, dh am endgültigen Block. Gleichzeitig wird die Rückgabe -0 -Anweisung im Programm in die Rückgabevariable im Stapel an die lokale Variable zusammengestellt, bevor die JSR -Anweisung aufgerufen wird, und die JSR -Anweisung wird aufgerufen, der schließlich wird ausgeführt und der schließlich der Block zurücksend. Wenn der Rückgabewert in der lokalen Variablen in den Stapel gedrückt wird, wird der Ireturn -Befehl ausgeführt, der Rückgabewert wird aus dem Stapel angezeigt und kehrt zur Anrufmethode zurück. Hier wird der Rückgabewert in der lokalen Variablen gespeichert, bevor die JSR -Anweisung ausgeführt wird, da eine Ausnahme während der Ausführung des endgültigen Blocks oder der Rückgabewerte auftreten kann. Nur auf diese Weise kann die Konsistenz der endgültigen Programmausführung sichergestellt werden. Da "Deeving Java Virtual Machine" seit einiger Zeit geschrieben wurde, unterscheidet sich die Implementierung und Version des vom Autor verwendeten JVM -Compilers auch von der in diesem Artikel beschriebenen. Nach dem Testen gibt es also einen kleinen Unterschied in der Erzeugung von Bytecodes für verschiedene Compiler -Implementierungen oder Versionen verschiedener Compiler für dasselbe Programm. Wenn Sie interessiert sind, können Sie sich den Bytecode ansehen, der von der endgültigen Klausel in diesem Buch erzeugt wird.
Die Bytecode-Generation in diesem Artikel wird durch die JDK8U-25-Version von Oracle des Compilers kompiliert und generiert.
Schauen wir uns ein Beispiel unten an.
1.Ry Catch endlich Beispiel:
public class Endlich test {public static void main (String [] args) {int r = test (); System.out.println (R); } public static int test () {try {system.out.println ("try"); // Rückkehr 1/0; Rückkehr 0; } catch (Ausnahme e) {System.out.println ("Ausnahme"); Rückkehr 100; } endlich {System.out.println ("endlich"); }}}Verwenden Sie die Anweisung return 0 im Try -Block, und das laufende Ergebnis des Programms lautet:
versuchen
Endlich
0
Verwenden Sie die Anweisung Rückgabe 1/0 im Try -Block, und das Ergebnis des ausgeführten Programms lautet:
Ausnahme
Endlich
100
Tatsächlich können wir durch das laufende Ergebnis sehen, dass der endgültige Block nach anderen Anweisungen vor der Rückgabeerklärung im Versuch oder Catch -Block ausgeführt wird. Mit anderen Worten, die Schreibreihenfolge des Programms entspricht nicht unserer Ausführungsreihenfolge, da JVM Bytecode interpretiert und ausführt. Daher müssen wir sehen, wie der Java -Compiler diesen Code kompiliert und sehen, wie die vom Bytecode aussieht.
2. Teil des vom Programms generierten Bytecode: (Bitte beachten Sie die Java -Bytecode -Anweisung)
öffentlicher statischer Int -Test (); Deskriptor: () I Flags: ACC_PUBLIC, ACC_STATISCHER CODE: STACK = 2, LOCALS = 2, Args_Size = 0 0: Getstatic #20 // Feld java/lang/system.out: ljava/io/printstream; 3: LDC #36 // String Try 5: invokevirtual #38 // Methode Java/io/printstream.println: (ljava/lang/string;) v 8: getstatic #20 // Feld java/lang/system.out: ljava/io/printream; 11: LDC #41 // String Endlich 13: InvokeVirtual #38 // Methode Java/io/printstream.println: (ljava/lang/string;) v 16: iconst_0 17: iReturn 18: store_0 19: getStatic #20 // field java/lang/system.out: ljava/io/printatream; 22: LDC #43 // String -Ausnahme 24: InvokeVirtual #38 // Methode Java/io/printstream.println: (ljava/lang/string;) v 27: getstatic #20 // Feld java/lang/system.out: ljava/io/printream; 30: LDC #41 // String Schließlich 32: InvokeVirtual #38 // Methode Java/io/printstream.println: (ljava/lang/string;) v 35: bipush 100 37: ireturn 38: store_1 39: getstatic #20/field java/lang/system.out: ljava/io/io/iten Java/lang/lang/system: ljava/io/io/io/io/io/I. 42: LDC #41 // String End
Aus dem roten Teil können wir sehen, dass die Zeilen 10 und 11 endlich Block -Anweisungsanweisungen 16 und 17 entsprechen. 19 und 20 entsprechen schließlich Blockanweisungen, 21 und 22 entsprechen den Anweisungen von Rückgabe 100 Anweisungen. Nachdem wir andere Aussagen gefangen haben und vor der Rückkehr sehen, können wir sehen, dass alles dahinter passiert, dass der Java -Compiler das alles für uns getan hat. Bei den Ausnahmen, die im Programm auftreten, wird JVM den entsprechenden Adressspeicherort für den Umgang mit Ausnahmen aus der Ausnahmeberabelle zur Ausführung finden.
Daher können wir zu dem Schluss kommen, dass die Aussagen in schließlich Blöcken vom Java -Compiler vor dem Block- und Catch -Block -Return -Anweisungen und nach den anderen Anweisungen eingefügt werden. Hier gibt es keine Unterprogramme, die JSR -Anrufe generieren. Aus diesem Grund wird der schließlich der Block ausgeführt, bevor die Methode zurückgegeben wird.
Die obige umfassende Analyse des Ausführungszeitpunkts von Java blockiert schließlich alle Inhalte, die ich mit Ihnen teile. Ich hoffe, Sie können Ihnen eine Referenz geben und ich hoffe, Sie können wulin.com mehr unterstützen.