Unterschied zwischen Try-finally und Try-Catch

88

Was ist der Unterschied zwischen

try {
    fooBar();
} finally {
    barFoo();
}

und

try {
  fooBar();
} catch(Throwable throwable) {
    barFoo(throwable); // Does something with throwable, logs it, or handles it.
}

Ich mag die zweite Version besser, weil sie mir Zugang zum Throwable gibt. Gibt es einen logischen Unterschied oder eine bevorzugte Konvention zwischen den beiden Variationen?

Gibt es auch eine Möglichkeit, auf die Ausnahme aus der finally-Klausel zuzugreifen?

Vijay Kotari
quelle

Antworten:

120

Dies sind zwei verschiedene Dinge:

  • Der catch-Block wird nur ausgeführt, wenn im try-Block eine Ausnahme ausgelöst wird.
  • Der finally-Block wird immer nach dem try-Block (-catch) ausgeführt, wenn eine Ausnahme ausgelöst wird oder nicht.

In Ihrem Beispiel haben Sie das dritte mögliche Konstrukt nicht gezeigt:

try {
    // try to execute this statements...
}
catch( SpecificException e ) {
    // if a specific exception was thrown, handle it here
}
// ... more catches for specific exceptions can come here
catch( Exception e ) {
    // if a more general exception was thrown, handle it here
}
finally {
    // here you can clean things up afterwards
}

Und wie @codeca in seinem Kommentar sagt, gibt es keine Möglichkeit, auf die Ausnahme innerhalb des finally-Blocks zuzugreifen, da der finally-Block ausgeführt wird, selbst wenn keine Ausnahme vorliegt.

Natürlich können Sie eine Variable deklarieren, die die Ausnahme außerhalb Ihres Blocks enthält, und einen Wert innerhalb des catch-Blocks zuweisen. Anschließend können Sie in Ihrem finally-Block auf diese Variable zugreifen.

Throwable throwable = null;
try {
    // do some stuff
}
catch( Throwable e ) {
    throwable = e;
}
finally {
    if( throwable != null ) {
        // handle it
    }
}
Tangens
quelle
11
Eine logische Folge davon ist , dass Sie nicht können den Zugriff Throwableaus dem finallyBlock, weil es nicht könnte sein ein Throwable.
Dean Harding
11

Dies sind keine Variationen, sondern grundlegend verschiedene Dinge. finallywird immercatch nur ausgeführt , wenn eine Ausnahme auftritt.

Michiel Buddingh
quelle
7

Schließlich und Fangblöcke sind ganz anders:

  • Innerhalb des catch-Blocks können Sie auf die ausgelöste Ausnahme reagieren. Dieser Block wird nur ausgeführt, wenn eine nicht behandelte Ausnahme vorliegt und der Typ mit dem übereinstimmt oder eine Unterklasse des im Parameter des catch-Blocks angegebenen ist.
  • Schließlich wird immer nach Try-and-Catch-Blöcken ausgeführt, ob eine Ausnahme ausgelöst wurde oder nicht.

So

try {
  //some code
}
catch (ExceptionA) {
  // Only gets executed if ExceptionA 
  // was thrown in try block
}
catch (ExceptionB) {
  // Only executed if ExceptionB was thrown in try 
  // and not handled by first catch block
}

unterscheidet sich von

try {
  //some code
}
finally {
  // Gets executed whether or not 
  // an exception was thrown in try block
}

bedeutend.

Wenn Sie einen Try-Block definieren, müssen Sie diesen definieren

  1. man blockiert schließlich, oder
  2. einen oder mehrere Fangblöcke oder
  3. ein oder mehrere Fangblöcke und ein Endblock

Der folgende Code wäre also auch gültig:

try {
  //some code
}
catch (ExceptionA) {
  // Only gets executed if 
  // ExceptionA was thrown in try block
}
catch (ExceptionB) {
  // Only executed if ExceptionB was thrown in 
  // try and not handled by first catch block
}
//even more catch blocks
finally {
  // Gets executed whether or not an 
  // exception was thrown in try block
}
TheMorph
quelle
4

try wird verwendet, um eine Methode auszuführen, die eine Ausnahme auslösen kann

catch wird verwendet, um diese Ausnahme zu "fangen"

finally wird für jede Bereinigung verwendet, die erforderlich ist, wenn diese Ausnahme abgefangen wird oder nicht

try{
    myObject.riskyMethod(); // run a method that may throw an exception
}
catch(Exception ex){
    myLogger.log(ex.Message); // "catch" stop that exception
}
finally{
    myObject = null; // clean up needed from that exception being caught
}
Kieran
quelle
3
try {
    statements;
} catch (exceptionType1 e1) {      // one or multiple
    statements;                 
} catch (exceptionType2 e2) {
    statements;
}    
...
} finally {                                 // one or none
    statements;
}
  1. Alle try-Anweisungen müssen entweder eine catch-Klausel oder eine finally-Klausel enthalten
  2. Es kann mehrere catch-Klauseln enthalten, aber nur eine finally-Klausel
  3. Wenn während einer Ausführung Fehler auftreten, wird das Steuerelement in den entsprechenden Catch-Block übertragen und führt die Anweisungen aus, und schließlich wird der Block ausgeführt.

Egal, was der finally-Block immer ausgeführt wird. Wenn also im Allgemeinen der finally-Block verwendet wird, wenn Sitzungen, Datenbankverbindungen oder Dateien oder Sockets geöffnet sind, wird der Code zum Schließen dieser Verbindungen platziert. Dies dient nur dazu, sicherzustellen, dass in einer Anwendung keine Speicherlecks oder andere Probleme auftreten.

gmhk
quelle
3

Schließlich und Fangblöcke sind ganz anders:

Innerhalb des catch-Blocks können Sie auf die ausgelöste Ausnahme reagieren. Dieser Block wird nur ausgeführt, wenn eine nicht behandelte Ausnahme vorliegt und der Typ mit dem übereinstimmt oder eine Unterklasse des im Parameter des catch-Blocks angegebenen ist. Schließlich wird immer nach Try-and-Catch-Blöcken ausgeführt, ob eine Ausnahme ausgelöst wurde oder nicht.

Android Tutorial
quelle
2

In My reasearch Schließlich wird der Block immer ausgeführt und hauptsächlich "zum Schließen offener Verbindungen" und zum Zerstören von unnötig laufenden Objekten verwendet.

Hari krishna
quelle
2

Wenn wir Ressourcen wie Streams, Verbindungen usw. verwenden, müssen wir diese im Allgemeinen explizit mit finally block schließen. In dem unten angegebenen Programm lesen wir Daten aus einer Datei mit FileReader und schließen sie mit finally block.

import java.io.File;
import java.io.FileReader;
import java.io.IOException;

public class ReadData_Demo {

   public static void main(String args[]){
      FileReader fr=null;       
      try{
         File file=new File("file.txt");
         fr = new FileReader(file);  char [] a = new char[50];
         fr.read(a); // reads the content to the array
         for(char c : a)
         System.out.print(c); //prints the characters one by one
      }catch(IOException e){
          e.printStackTrace();
       }
       finally{ 
          try{
              fr.close();
          }catch(IOException ex){       
               ex.printStackTrace();
           }
       }
    }

}

Vielleicht haben andere Leute wie ich nach so etwas gesucht.

Informationen von dieser Seite tutpoint


quelle
1

Schließlich wird der Block immer ausgeführt. Der Catch-Block wird nur ausgeführt, wenn eine Ausnahme abgefangen wird, die dem Block-Parameter entspricht.

mkorpela
quelle
1

Bereits im ersten Formular können Sie es in der aufrufenden Methode protokollieren. Es gibt also keinen großen Vorteil, es sei denn, Sie möchten genau dort ein spezielles Handling durchführen.

fastcodejava
quelle
0

Der Try-Block enthält die Anweisungen, die eine Ausnahme auslösen. Der catch-Block enthält die vom try-Block ausgelöste Referenz, und die erforderlichen Nachrichten werden vom catch-Block generiert. Schließlich wird der Block auch verwendet, um die verwendeten Ressourcen zu schließen, wie z. B. Schließen von Dateien, Schließen von Dateien, Schließen von dB. In Java-9 wurde eine erweiterte Try-With-Ressource verwendet, bei der die Ressourcen außerhalb des Try deklariert wurden ist obligatorisch

Srinija
quelle