2013-08-08 14 views
22

Ich bin verwirrt über die try-finally-Ausführung, wenn return; im try-Block existiert. Nach meinem Verständnis wird der finally-Block immer ausgeführt, d. H. Bevor zu der aufrufenden Methode zurückgekehrt wird. Unter Berücksichtigung des folgenden einfachen Codes:java: try beendet schließlich die Ausführung

Das Ergebnis gedruckt ist eigentlich 1. Bedeutet dies, dass der endgültige Block nicht ausgeführt wird? Kann mir jemand dabei helfen?

+1

Warum fügen Sie eine 'System.out.println()' zum finally Block hinzu und sehen Sie sich? Ich denke, es wird ausgeführt, aber der zurückgegebene Wert ist 1. –

+0

Wenn Sie try catch verwenden, können Sie bestimmte Arten von Ausnahmen "fangen" (zB: IOException, NullPointerException etc ..) Die finally-Anweisung tritt auf, wenn die spezifische Ausnahme passiert und Sie müssen führe irgendeinen Code vor dem Fang aus ... – RicardoE

+7

[Hier ist] (http://StackOverflow.com/questions/Tagged/Java+Return+Finally?Sort=votes&pagesize=40) etwas zum Nachdenken über – keyser

Antwort

23

Wenn Sie vom try Block zurückkehren, wird der Rückgabewert im Stapelrahmen für diese Methode gespeichert. Danach wird der finally-Block ausgeführt.

Durch Ändern des Werts im finally-Block wird der Wert auf dem Stapel nicht geändert. Wenn Sie jedoch erneut aus dem finally-Block zurückkehren, wird der Rückgabewert auf dem Stapel überschrieben und das neue x wird zurückgegeben.

Wenn Sie den Wert von x in endlich Block drucken, werden Sie erfahren, dass es ausgeführt wird, und der Wert x wird gedruckt.

static int test(){ 
    int x = 1; 
    try{ 
     return x; 
    } 
    finally{ 
     x = x + 1; 
     System.out.println(x); // Prints new value of x 
    } 
} 

Anmerkung: Bei einem Referenzwert zurückgeführt wird, wird der Wert der Referenz auf dem Stapel abgelegt. In diesem Fall können Sie den Wert des Objekts mithilfe dieser Referenz ändern.

StringBuilder builder = new StringBuilder(""); 
try { 
    builder.append("Rohit "); 
    return builder; 

} finally { 
    // Here you are changing the object pointed to by the reference 
    builder.append("Jain"); // Return value will be `Rohit Jain` 

    // However this will not nullify the return value. 
    // The value returned will still be `Rohit Jain` 
    builder = null; 
} 

Empfohlene lesen:

+0

dang, schlag mich dazu! –

+7

Hinzufügen: Nur der return * value * selbst wird auf dem Stack gespeichert. Wenn Sie einen Verweis auf ein Objekt zurückgeben, sind Änderungen an den Feldern des Objekts, die im Block "finally" vorgenommen wurden, weiterhin sichtbar. –

+0

@JasonC. Jawohl. Wird zur Antwort hinzufügen. Danke :) –

10

Der finally-Block ausgeführt wird. Die lokale Variable wird inkrementiert. Der Wert dieser lokalen Variablen wurde jedoch bereits für den Rückgabewert kopiert.

Aus der Java Language Specification, 14.17: The return statement:

Eine return-Anweisung mit einem Ausdruck versucht, die Kontrolle an die Aufrufer des Verfahrens zu übertragen, die es enthält; Der Wert des Ausdrucks wird zum Wert des Methodenaufrufs.

...

Die vorstehenden Beschreibungen sagen „versucht, die Kontrolle zu übertragen“ und nicht nur „übertragen Kontrolle“, weil, wenn es irgendwelche Aussagen versuchen (§14.20) innerhalb der Methode oder Konstruktor deren versuchen, Blöcke oder catch-Klauseln enthalten die return-Anweisung, dann werden alle abschließend Klauseln dieser try-Anweisungen in der Reihenfolge innermost bis äußerste ausgeführt, bevor die Steuerung an den Aufrufer der Methode oder des Konstruktors übergeben wird. Abrupte Abschluss einer schließlich Klausel kann die Übertragung der Kontrolle durch eine return-Anweisung eingeleitet stören

+3

Nun, ich vermute * jemand * musste die Dokumentation tatsächlich lesen. Jede Party hat einen Scheißkerl. –

0

Sie x zurückkehren, bevor Sie verlassen versuchen.Ich würde dies tun:

public class TryCatchTest { 
    public static void main(String[] args) { 
     System.out.println(test()); 
    } 
    static int test() { 
     int x = 1; 
     try { 
      do something with x. 
     } finally { 
      do something that will happen even in case of error; 
      x = x + 1; 
      return x; 
     } 
    } 
} 
+1

Ich denke, das vermisst den Punkt. –