Différence entre try-finally et try-catch

90

Quelle est la différence entre

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

et

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

J'aime mieux la deuxième version car elle me donne accès au Throwable. Y a-t-il une différence logique ou une convention préférée entre les deux variantes?

Existe-t-il également un moyen d'accéder à l'exception de la clause finally?

Vijay Kotari
la source

Réponses:

121

Ce sont deux choses différentes:

  • Le bloc catch n'est exécuté que si une exception est levée dans le bloc try.
  • Le bloc finally est exécuté toujours après le bloc try (-catch), si une exception est levée ou non.

Dans votre exemple, vous n'avez pas montré la troisième construction possible:

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
}

Et, comme le dit @codeca dans son commentaire, il n'y a aucun moyen d'accéder à l'exception à l'intérieur du bloc finally, car le bloc finally est exécuté même s'il n'y a pas d'exception.

Bien sûr, vous pouvez déclarer une variable qui contient l'exception en dehors de votre bloc et attribuer une valeur à l'intérieur du bloc catch. Ensuite, vous pouvez accéder à cette variable dans votre bloc finally.

Throwable throwable = null;
try {
    // do some stuff
}
catch( Throwable e ) {
    throwable = e;
}
finally {
    if( throwable != null ) {
        // handle it
    }
}
tangens
la source
11
Un corollaire est que vous ne pouvez pas accéder au Throwabledu finallybloc, car il pourrait ne pas être un Throwable.
Dean Harding
11

Ce ne sont pas des variations, ce sont des choses fondamentalement différentes. finallyest toujours exécuté , catchuniquement lorsqu'une exception se produit.

Michiel Buddingh
la source
7

Enfin et les blocs catch sont assez différents:

  • Dans le bloc catch, vous pouvez répondre à l'exception levée. Ce bloc est exécuté uniquement s'il existe une exception non gérée et que le type correspond à celui ou est une sous-classe de celui spécifié dans le paramètre du bloc catch.
  • Enfin sera toujours exécuté après les blocs try and catch, qu'il y ait une exception levée ou non.

Alors

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
}

diffère de

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

significativement.

Si vous définissez un bloc try, vous devez définir

  1. un enfin bloc, ou
  2. un ou plusieurs blocs catch, ou
  3. un ou plusieurs blocs catch et un bloc finally

Donc, le code suivant serait également valide:

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
la source
4

try est utilisé pour exécuter une méthode qui peut lever une exception

catch est utilisé pour "attraper" arrêter cette exception

finally est utilisé pour tout nettoyage nécessaire à partir de cette exception interceptée ou non

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
la source
3
try {
    statements;
} catch (exceptionType1 e1) {      // one or multiple
    statements;                 
} catch (exceptionType2 e2) {
    statements;
}    
...
} finally {                                 // one or none
    statements;
}
  1. Toutes les instructions try doivent inclure une clause catch ou une clause finally
  2. Il peut avoir plusieurs clauses catch mais une seule clause finally
  3. Pendant toute exécution, si des erreurs se produisent, alors le contrôle est transféré au bloc Catch approprié et exécute les instructions et le bloc Enfin est exécuté.

Peu importe ce que le bloc Enfin est toujours exécuté, donc en général, le bloc Enfin est utilisé, lorsque vous avez des sessions, des connexions de base de données ou des fichiers ou des sockets sont ouverts, le code de fermeture de ces connexions sera placé. C'est juste pour s'assurer que dans une application aucune fuite de mémoire ou aucun autre problème ne devrait se produire.

gmhk
la source
3

Enfin et les blocs catch sont assez différents:

Dans le bloc catch, vous pouvez répondre à l'exception levée. Ce bloc est exécuté uniquement s'il existe une exception non gérée et que le type correspond à celui ou est une sous-classe de celui spécifié dans le paramètre du bloc catch. Enfin sera toujours exécuté après les blocs try and catch, qu'il y ait une exception levée ou non.

Tutoriel Android
la source
2

Dans Mes recherches, le bloc Enfin est toujours exécuté et il est principalement "utilisé pour fermer les connexions ouvertes" et pour détruire quelque chose qui tourne inutilement.

Hari Krishna
la source
2

Généralement, lorsque nous utilisons des ressources telles que des flux, des connexions, etc., nous devons les fermer explicitement en utilisant le bloc finally. Dans le programme donné ci-dessous, nous lisons les données d'un fichier en utilisant FileReader et nous le fermons en utilisant le bloc finally.

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();
           }
       }
    }

}

Peut-être que d'autres types comme moi ont cherché quelque chose comme ça.

Informations de cette page tutpoint


la source
1

Enfin, le bloc est toujours exécuté. Catch block est exécuté uniquement lorsqu'une exception correspondant au paramètre blocks est interceptée.

mkorpela
la source
1

Même dans le premier formulaire, vous pouvez l'enregistrer dans la méthode d'appel. Il n'y a donc pas de gros avantage à moins que vous ne souhaitiez effectuer une manipulation spéciale sur place.

fastcodejava
la source
0

Try block contiendra les instructions qui vont déclencher une exception. Le bloc catch contiendra la référence lancée depuis le bloc try et les messages requis sont générés à partir du bloc catch. Enfin, le bloc est également utilisé pour fermer les ressources utilisées telles que la fermeture de io, la fermeture de fichier, la fermeture de dB. est obligatoire

srinija
la source