103 votes

lance l'exception dans les blocs finaux

Existe-t-il une manière élégante de traiter les exceptions qui sont lancées dans finally bloc ?

Par exemple :

try {
  // Use the resource.
}
catch( Exception ex ) {
  // Problem with the resource.
}
finally {
   try{
     resource.close();
   }
   catch( Exception ex ) {
     // Could not close the resource?
   }
}

Comment éviter le try / catch dans le finally bloc ?

73voto

Darron Points 13196

Je fais généralement comme ça :

try {
  // Use the resource.
} catch( Exception ex ) {
  // Problem with the resource.
} finally {
  // Put away the resource.
  closeQuietly( resource );
}

Ailleurs :

protected void closeQuietly( Resource resource ) {
  try {
    if (resource != null) {
      resource.close();
    }
  } catch( Exception ex ) {
    log( "Exception during Resource.close()", ex );
  }
}

5 votes

Oui, j'utilise un idiome très similaire. Mais je ne crée pas de fonction pour cela.

9 votes

Une fonction est pratique si vous devez utiliser l'idiome à plusieurs endroits dans la même classe.

0 votes

La vérification de la nullité est redondante. Si la ressource est nulle, alors la méthode d'appel est cassée et doit être corrigée. De même, si la ressource est nulle, cela devrait probablement être enregistré. Sinon, il en résulte une exception potentielle qui est ignorée en silence.

26voto

CJS Points 460

J'utilise généralement l'un des closeQuietly méthodes en org.apache.commons.io.IOUtils :

public static void closeQuietly(OutputStream output) {
    try {
        if (output != null) {
            output.close();
        }
    } catch (IOException ioe) {
        // ignore
    }
}

3 votes

Vous pouvez rendre cette méthode plus générale avec Closeable public static void closeQuietly(Closeable closeable) {

6 votes

Oui, Closeable est bien. C'est une honte que beaucoup de choses (comme les ressources JDBC) ne l'implémentent pas.

22voto

Kevin Wong Points 3730

Si vous utilisez Java 7, et resource met en œuvre AutoClosable vous pouvez le faire (en utilisant InputStream comme exemple) :

try (InputStream resource = getInputStream()) {
  // Use the resource.
}
catch( Exception ex ) {
  // Problem with the resource.
}

8voto

MB. Points 2847

On peut dire que c'est un peu exagéré, mais c'est peut-être utile si vous laissez les exceptions s'accumuler et que vous ne pouvez rien consigner à l'intérieur de votre méthode (par exemple, parce que c'est une bibliothèque et que vous préférez laisser le code appelant gérer les exceptions et la consignation) :

Resource resource = null;
boolean isSuccess = false;
try {
    resource = Resource.create();
    resource.use();
    // Following line will only run if nothing above threw an exception.
    isSuccess = true;
} finally {
    if (resource != null) {
        if (isSuccess) {
            // let close throw the exception so it isn't swallowed.
            resource.close();
        } else {
            try {
                resource.close();
            } catch (ResourceException ignore) {
                // Just swallow this one because you don't want it 
                // to replace the one that came first (thrown above).
            }
        }
    }
}

MISE À JOUR : J'ai examiné cette question un peu plus en détail et j'ai trouvé un excellent article sur le blog de quelqu'un qui a manifestement réfléchi à cette question plus que moi : http://illegalargumentexception.blogspot.com/2008/10/java-how-not-to-make-mess-of-stream.html Il va plus loin et combine les deux exceptions en une seule, ce qui pourrait être utile dans certains cas.

1 votes

+1 pour le lien vers le blog. En outre, j'enregistrerais au moins le ignore exception

2voto

Pierre Points 15256

Une solution, si les deux Exceptions sont deux classes différentes

try {
    ...
    }
catch(package1.Exception err)
   {
    ...
   }
catch(package2.Exception err)
   {
   ...
   }
finally
  {
  }

Mais parfois, vous ne pouvez pas éviter ce deuxième try-catch, par exemple pour fermer un flux.

InputStream in=null;
try
 {
 in= new FileInputStream("File.txt");
 (..)// do something that might throw an exception during the analysis of the file, e.g. a SQL error
 }
catch(SQLException err)
 {
 //handle exception
 }
finally
 {
 //at the end, we close the file
 if(in!=null) try { in.close();} catch(IOException err) { /* ignore */ }
 }

0 votes

Dans votre cas, si vous avez utilisé une déclaration "using", cela devrait nettoyer la ressource.

0 votes

C'est ma faute, je suppose que c'est du C#.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X