Java-return Wert im try-catch-finally-Mechanismus
Ich habe gerade stieß dieses folgenden code:
public class TestFinally {
public static void main(String[] args) {
int returnValue = function();
System.out.println("Return value: " + returnValue);
}
public static int function() {
try {
return 1;
} catch (Exception e){
return 2;
} finally{
return 3;
}
}
}
Es ist ohne Zweifel, dass dieser code ausgeführt wird, ergeben eine Ausgabe von "Rückgabewert 3".
Allerdings bin ich neugierig, wie:
- Der Mechanismus, der die Innereien in der JVM. Weiß jemand, ob die VM tatsächlich ersetzt der Rückgabewert auf dem stack durch über-schreiben die erste "return 1"? Wenn ja, wo finde ich mehr Informationen über diese.
- Habe ich noch nicht gefunden, der Einsatz für ein return im finally-Mechanismus, der auf diese Weise und erlaubt in der implementierten
in der JVM. Wenn dieses code-Konstrukt wird verwendet als ein Mittel, um zurückzukehren
Fehler-code -, ist es meiner Meinung nach gibt es bessere Möglichkeiten, um Fehler zu protokollieren
oder kehren diese Fehler-codes. Es hat sich jemand gefunden, der einen solchen
konstruieren?
Vielen Dank im Voraus.
Cheers,
Vern
- zu 1.: keine Ahnung, ich möchte das auch wissen. zu 2.: schließlich kann verwendet werden, um zu tun, meint, dass unbedingt erledigt werden müssen, z.B. schließen von streams. Ich denke Ausnahmen sind schöner als die Fehler-codes, denn Sie sehen bereits in der Methoden-Signatur, was könnte schief gehen (ohne Lesen irgendeiner Dokumentation), und es ist schwieriger zu ignorieren Sie Sie einfach für die coder.
- Naja, kann ich nicht wirklich beantworten das erste, aber das zweite scheint ziemlich offensichtlich. Die finally-Klausel wird verwendet, um aufzuräumen (wie nah-streams), was muss geschehen, selbst wenn der code gibt. Jedoch, Rückkehr in eine finally-Klausel ist eine schlechte Praxis sowieso, nur tun Sie es nicht.
- Ich glaube nicht, Sie sind ment zu ändern Rückgabewert innerhalb finnaly block, aber warum sollte Sie auf der anderen Seite dossallow Sie es zu tun? Aber es ist nicht eine gute pracice zu tun.
- Vielen Dank an alle für den input. Ja, ich erkannte, dass die Frage, die ich stellte, war nicht klar. Ich habe bearbeitet und geklärt die Frage. Ich bin gespannt, ob jemand gesehen hat, einen solchen code zu verwenden, wobei eine Rückgabe erfolgt in den try-block und einem zweiten return im finally-block zu überschreiben, der try-block den Rückgabewert. Hat jemand mal so einen verwenden?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Was ich in der Java language specification mindestens definiert, dass der code-snippet sollte die Rückkehr 3. Natürlich, es nicht zu erwähnen, wie die JVM zu implementieren sollte, und was mögliche Optimierungen, die man tun konnte.
Abschnitt 14.20.2 definiert, dass
Und der Beginn der chapter14 (Abschnitt 14.1 um genauer zu sein) gibt, was eine normale und abrupte Abschluss ist. Zum Beispiel ein
return
mit einem bestimmten Wert ist eine abrupte Beendigung.Daher in diesem Fall die
finally
block schließt abrupt (Grund:return
mit einem bestimmten Wert), so dass dietry
abgeschlossen wird abrupt aus dem gleichen Grund (und zurück 3). Dies wird bestätigt in Abschnitt 14.17 über die return-Anweisung sowieFWIW, ich bekomme eine Warnung, die auf Funktion:
Ie. es sagt mir "finally-block nicht regulär abgeschlossen". Ich bekomme immer noch 3 als Rückgabewert, egal was.
Jedenfalls, wenn ich versuche das andere Beispiel:
wird die Ausgabe sein (natürlich)
Ich habe keine Ahnung, wie die JVM implementiert haben, aber der einfachste Weg, es zu betrachten (zumindest konzeptionell) wäre:
Sehr nette Frage in der Tat.
Die Umsetzung ist bis auf die JVM, und es gibt viele JVMs. Sie Graben in OpenJDK-Quellcode zu sehen, wie es implementiert
finally
, aber das wäre nicht der einzige Weg, es zu tun. Soweit es die Sprache betrifft, das wichtigste ist das Verhalten.Ich verstehe nicht, Punkt 2-warum tut
finally
vorhanden??? es ist nicht wie Sie suggerieren irgendwie nur ein Mittel, um einen Fehler zurück-code. Sie nicht haben, um die Rückkehr von innerhalbfinally
überhaupt. Das Konstrukt vorhanden ist, um sicherzustellen, dass irgendeine Art von clean-up-code, der ausgeführt wird, nachdem einige code-Abschnitt, der egal, wie es endet, ob normal oder per exception oder return.Vollständig erklärt werden, Seite:439=>
http://docs.oracle.com/javase/specs/jls/se8/jls8.pdf
Wenn die Auswertung des Ausdrucks wird normal ausgeführt, wodurch eine
Wert V, dann die return-Anweisung abgeschlossen ist abrupt, der Grund dafür ist eine Rückkehr
mit Wert V.
Den vorangehenden Beschreibungen sagen, "versuche zur übertragung von Steuer -" anstatt nur "transfers
Kontrolle", denn wenn es irgendwelche try-Anweisungen (§14.20) innerhalb der Methode oder Konstruktor
dessen try-blocks im catch-Klauseln enthalten, die return-Anweisung, dann werden alle endlich
Klauseln dieser try-Anweisungen ausgeführt werden, in der Reihenfolge, innersten zum äußersten, bevor
die Steuerung an den Aufrufer der Methode oder eines Konstruktors. Abrupte Abschluss einer
finally-Klausel stören die übertragung der Kontrolle, initiiert durch eine return-Anweisung.