Try-Catch-Finally-Return-Klärung

Durch das Lesen aller Fragen, die bereits in diesem Forum zu dem oben genannten Thema gestellt wurden (siehe Titel), verstehe ich ganz genau, dass finally immer aufgerufen wird. (außer von System.exit und Endlosschleifen). Allerdings würde ich gerne wissen, ob eine return in einem catch-Block aufgerufen wird und dann eine andere return vom finally-Block aufgerufen wird.

Beispielsweise:

 public static void main(String[]args) { int a = new TestClass().absorbeTheValue(); } int absorbeTheValue() { try { int a = 10/0; if (a > 0) return 4; } catch(Exception e) { return 45; } finally { return 34; } } 

Also hier wird die Ausgabe (wenn die Methode aufgerufen wird) auf jeden Fall 34 sein. Es bedeutet, dass schließlich immer ausgeführt wird. Ich denke aber, dass die anderen “Returns” überhaupt nicht laufen. In vielen Beiträgen fand ich die Tatsache, dass endlich der Inhalt über das geschrieben wurde, was schon durch die Rückgabeklausel geschrieben wurde. Mein Verständnis ist, dass, sobald der Rückgabewert in der catch-Klausel evaluiert wird, der Kontrollfluss an die finally-Klausel übergeben wird, die wiederum eine weitere Rückgabe hat, diesmal wird die Rückgabe ausgewertet, ohne die Kontrolle an die catch-Klausel zurückzugeben . Auf diese Weise wird die einzige zur Laufzeit aufgerufene return die endgültige Rückkehr sein. Sind Sie einverstanden (damit?

Ein return in gibt das Steuerelement nicht an das Programm zurück, sondern gibt den Wert zurück und beendet die Methode. Können wir das sagen?

   

Wenn die return im try Block erreicht ist, überträgt sie die Kontrolle an den finally Block, und die function kehrt schließlich normal zurück (kein throw).

Wenn eine Ausnahme auftritt, aber dann der Code eine return vom catch Block erreicht, wird die Kontrolle an den finally Block übergeben und die function kehrt schließlich normal zurück (kein throw).

In Ihrem Beispiel haben Sie eine return in das Finale, und unabhängig davon, was passiert, wird die function 34 , weil finally das letzte (wenn Sie so wollen) Wort hat.

Obwohl dies in Ihrem Beispiel nicht behandelt wird, wäre dies auch dann der Fall, wenn Sie den catch und eine Exception in den try Block geworfen und nicht abgefangen wurde. Durch eine return des finally Blocks unterdrücken Sie die Ausnahme vollständig. Erwägen:

 public class FinallyReturn { public static final void main(String[] args) { System.out.println(foo(args)); } private static int foo(String[] args) { try { int n = Integer.parseInt(args[0]); return n; } finally { return 42; } } } 

Wenn Sie das ausführen, ohne irgendwelche Argumente zu liefern:

  $ java FinallyReturn 

… der Code in foo ArrayIndexOutOfBoundsException eine ArrayIndexOutOfBoundsException . Da der finally Block jedoch eine return , wird diese Ausnahme unterdrückt.

Dies ist ein Grund, warum es am besten ist, die Verwendung von return finally zu vermeiden.

Hier ist ein Code, der zeigt, wie es funktioniert.

 class Test { public static void main(String args[]) { System.out.println(Test.test()); } public static String test() { try { System.out.println("try"); throw new Exception(); } catch(Exception e) { System.out.println("catch"); return "return"; } finally { System.out.println("finally"); return "return in finally"; } } } 

Die Ergebnisse sind:

 try catch finally return in finally