Frage Wird letztendlich immer in Java ausgeführt?
Betrachte diesen Code, kann ich sein absolut sicher dass die finally
Block wird immer ausgeführt, egal was passiert something()
ist?
try {
something();
return success;
}
catch (Exception e) {
return failure;
}
finally {
System.out.println("i don't know if this will get printed out.");
}
1901
2017-09-15 17:43
Ursprung
Antworten:
Ja, finally
wird nach der Ausführung der Versuchs- oder Fangcode-Blöcke aufgerufen.
Die einzigen Zeiten finally
werden nicht angerufen werden:
- Wenn Sie aufrufen
System.exit()
;
- Wenn die JVM zuerst abstürzt;
- Wenn die JVM eine Endlosschleife (oder eine andere nicht unterbrechbare, nicht terminierende Anweisung) in der
try
oder catch
Block;
- Wenn das Betriebssystem den JVM-Prozess zwangsweise beendet; z.B. "kill -9" unter UNIX.
- Wenn das Host-System stirbt; z.B. Stromausfall, Hardwarefehler, OS Panik, und so weiter.
- Wenn schließlich der Block vom Daemon-Thread ausgeführt wird und alle anderen Nicht-Daemon-Threads beendet werden, bevor schließlich aufgerufen wird.
2114
2017-09-15 17:45
Beispielcode:
public static void main(String[] args) {
System.out.println(Test.test());
}
public static int test() {
try {
return 0;
}
finally {
System.out.println("finally trumps return.");
}
}
Ausgabe:
finally trumps return.
0
444
2017-09-15 17:59
Auch wenn es eine schlechte Übung ist, wird es, wenn innerhalb des finally-Blocks eine return-Anweisung vorhanden ist, jede andere Rückkehr aus dem regulären Block übertrumpfen. Das heißt, der folgende Block würde false zurückgeben:
try { return true; } finally { return false; }
Das Gleiche gilt für das Auslösen von Ausnahmen vom finally-Block.
323
2017-09-15 18:19
Hier sind die offiziellen Worte aus der Java Language Specification.
14.20.2. Ausführung von try-finally und try-catch-finally
EIN try
Aussage mit a finally
Der Block wird ausgeführt, indem zuerst der Befehl ausgeführt wird try
Block. Dann gibt es eine Wahl:
- Wenn die Ausführung der
try
Block wird normal abgeschlossen, [...]
- Wenn die Ausführung der
try
Der Block wird abrupt wegen a beendet throw
eines Wertes V, [...]
- Wenn die Ausführung der
try
Block wird aus irgendeinem anderen Grund abrupt beendet R, dann ist die finally
Block wird ausgeführt. Dann gibt es eine Wahl:
- Wenn der finally Block normal beendet wird, dann wird der
try
Die Anweisung wird abrupt beendet R.
- Wenn die
finally
Der Block wird abrupt beendet S, dann ist die try
Die Anweisung wird abrupt beendet S (und Grund R wird verworfen).
Die Spezifikation für return
macht dies explizit:
JLS 14.17 Die Rückkehrerklärung
ReturnStatement:
return Expression(opt) ;
EIN return
Aussage mit Nein Expression
Versuche Übergeben der Kontrolle an den Aufrufer der Methode oder des Konstruktors, der sie enthält.
EIN return
Aussage mit einem Expression
Versuche die Kontrolle auf den Aufrufer der Methode zu übertragen, die sie enthält; der Wert des Expression
wird zum Wert des Methodenaufrufs.
Die vorhergehenden Beschreibungen sagen "Versuche um die Kontrolle zu übertragen" anstatt nur "überträgt die Kontrolle"Denn wenn es welche gibt try
Anweisungen innerhalb der Methode oder des Konstruktors, deren try
Blöcke enthalten die return
Aussage, dann irgendwelche finally
Klauseln von denen try
Anweisungen werden in der Reihenfolge innerlich nach äußerste ausgeführt, bevor die Kontrolle an den Aufrufer der Methode oder des Konstruktors übergeben wird. Abrupte Vollendung eines finally
Klausel kann den Kontrollübergang stören, der von a return
Erklärung.
229
2018-05-25 06:50
Zusätzlich zu den anderen Antworten ist es wichtig, darauf hinzuweisen, dass "endlich" das Recht hat, jede Ausnahme / jeden zurückgegebenen Wert durch den try..catch-Block zu überschreiben. Der folgende Code gibt beispielsweise 12 zurück:
public static int getMonthsInYear() {
try {
return 10;
}
finally {
return 12;
}
}
In ähnlicher Weise löst die folgende Methode keine Ausnahme aus:
public static int getMonthsInYear() {
try {
throw new RuntimeException();
}
finally {
return 12;
}
}
Während die folgende Methode es wirft:
public static int getMonthsInYear() {
try {
return 12;
}
finally {
throw new RuntimeException();
}
}
134
2018-05-13 07:11
Ich habe das obige Beispiel mit leichten Modifikationen versucht-
public static void main(final String[] args) {
System.out.println(test());
}
public static int test() {
int i = 0;
try {
i = 2;
return i;
} finally {
i = 12;
System.out.println("finally trumps return.");
}
}
Der obige Code gibt aus:
Endlich kehrt die Trümpfe zurück.
2
Dies ist weil return i;
wird ausgeführt i
hat einen Wert von 2. Danach finally
Block wird ausgeführt, wo 12 zugewiesen ist i
und dann System.out
out wird ausgeführt.
Nach dem Ausführen der finally
blockiere die try
block gibt 2 zurück, anstatt 12 zurückzugeben, da diese return-Anweisung nicht erneut ausgeführt wird.
Wenn Sie diesen Code in Eclipse debuggen, werden Sie nach der Ausführung ein Gefühl bekommen System.out
von finally
blockiere die return
Aussage von try
Block wird erneut ausgeführt. Aber das ist nicht der Fall. Es gibt einfach den Wert 2 zurück.
88
2017-11-17 16:25
Hier ist eine Ausarbeitung von Kevins Antwort. Es ist wichtig zu wissen, dass der auszugebende Ausdruck vorher ausgewertet wird finally
, auch wenn es danach zurückgegeben wird.
public static void main(String[] args) {
System.out.println(Test.test());
}
public static int printX() {
System.out.println("X");
return 0;
}
public static int test() {
try {
return printX();
}
finally {
System.out.println("finally trumps return... sort of");
}
}
Ausgabe:
X
finally trumps return... sort of
0
80
2017-12-03 23:36
Das ist die ganze Idee eines Endblocks. Dadurch können Sie natürlich sicherstellen, dass Sie Aufräumarbeiten durchführen, die sonst möglicherweise übersprungen werden, weil Sie unter anderem natürlich zurückkehren.
Endlich wird angerufen egal was passiert im Versuchsblock (es sei denn du rufst an System.exit(int)
oder die Java Virtual Machine startet aus einem anderen Grund).
46
2018-05-13 06:19
Ein logischer Weg, darüber nachzudenken, ist:
- Code in einem finally Block muss ausgeführt werden was auch immer geschieht innerhalb des Versuchsblocks
- Wenn der Code im try-Block versucht, einen Wert zurückzugeben oder eine Ausnahme auszulösen, wird der Artikel "im Regal" platziert, bis der finally-Block ausgeführt werden kann
- Da Code im finally-Block (definitionsgemäß) eine hohe Priorität hat, kann er beliebig zurückgeben oder werfen. In diesem Fall wird alles, was auf dem Regal liegt, verworfen.
- Die einzige Ausnahme besteht darin, dass die VM während des try-Blocks z. von 'System.exit'
31
2017-09-15 19:26