web-dev-qa-db-fra.com

Puis-je intercepter plusieurs exceptions Java dans la même clause catch?

En Java, je veux faire quelque chose comme ça:

try {
    ...     
} catch (/* code to catch IllegalArgumentException, SecurityException, 
            IllegalAccessException, and NoSuchFieldException at the same time */) {
   someCode();
}

...au lieu de:

try {
    ...     
} catch (IllegalArgumentException e) {
    someCode();
} catch (SecurityException e) {
    someCode();
} catch (IllegalAccessException e) {
    someCode();
} catch (NoSuchFieldException e) {
    someCode();
}

Est-ce qu'il y a un moyen de faire ça?

648
froadie

Cela a été possible depuis Java 7 . La syntaxe d'un bloc multi-captures est la suivante:

try { 
  ...
} catch (IOException | SQLException ex) { 
  ...
}

Rappelez-vous cependant que si toutes les exceptions appartiennent à la même hiérarchie de classes, vous pouvez simplement intercepter ce type d'exception de base.

Notez également que vous ne pouvez pas capturer ExceptionA et ExceptionB dans le même bloc si ExceptionB est hérité, directement ou indirectement, de ExceptionA. Le compilateur va se plaindre:

Alternatives in a multi-catch statement cannot be related by subclassing
  Alternative ExceptionB is a subclass of alternative ExceptionA
1060
OscarRyz

Pas exactement avant Java 7, mais je voudrais faire quelque chose comme ceci:

Java 6 et avant

try {
  //.....
} catch (Exception exc) {
  if (exc instanceof IllegalArgumentException || exc instanceof SecurityException || 
     exc instanceof IllegalAccessException || exc instanceof NoSuchFieldException ) {

     someCode();

  } else if (exc instanceof RuntimeException) {
     throw (RuntimeException) exc;     

  } else {
    throw new RuntimeException(exc);
  }

}



Java 7

try {
  //.....
} catch ( IllegalArgumentException | SecurityException |
         IllegalAccessException |NoSuchFieldException exc) {
  someCode();
}
102
user454322

Dans Java 7, vous pouvez définir plusieurs clauses catch telles que:

catch (IllegalArgumentException | SecurityException e)
{
    ...
}
23
crusam

Non, un par client.

Vous pouvez attraper une super-classe, telle que Java.lang.Exception, à condition que vous exécutiez la même action dans tous les cas.

try {
    // some code
} catch(Exception e) { //All exceptions are caught here as all are inheriting Java.lang.Exception
    e.printStackTrace();
}

Mais cela pourrait ne pas être la meilleure pratique. Vous ne devez intercepter une exception que lorsque vous avez une stratégie pour la gérer réellement - et que la journalisation et le réenregistrement ne constituent pas une "gestion". Si vous ne disposez pas d'une action corrective, il est préférable de l'ajouter à la signature de la méthode et de la laisser apparaître à quelqu'un qui peut gérer la situation.

15
duffymo

S'il existe une hiérarchie d'exceptions, vous pouvez utiliser la classe de base pour intercepter toutes les sous-classes d'exceptions. Dans le cas dégénéré, vous pouvez attraper tous Java exceptions avec:

try {
   ...
} catch (Exception e) {
   someCode();
}

Dans un cas plus courant, si RepositoryException est la classe de base et PathNotFoundException est une classe dérivée, alors:

try {
   ...
} catch (RepositoryException re) {
   someCode();
} catch (Exception e) {
   someCode();
}

Le code ci-dessus intercepte les exceptions RepositoryException et PathNotFoundException pour un type de gestion des exceptions et toutes les autres exceptions sont regroupées. Depuis Java 7, comme indiqué dans la réponse de @ OscarRyz ci-dessus:

try { 
  ...
} catch( IOException | SQLException ex ) { 
  ...
}
13
Michael Shopsin

Une alternative plus propre (mais moins verbeuse, et peut-être pas préférée) à la réponse de user454322 sur Java 6 (c'est-à-dire Android) consisterait à capturer toutes les Exceptions et à les relancer RuntimeExceptions . Cela ne fonctionnerait pas si vous envisagiez de capturer d'autres types d'exceptions plus loin dans la pile (sauf si vous les relancez également), mais capturera effectivement toutes les cochées exceptions.

Par exemple:

try {
    // CODE THAT THROWS EXCEPTION
} catch (Exception e) {
    if (e instanceof RuntimeException) {
        // this exception was not expected, so re-throw it
        throw e;
    } else {
        // YOUR CODE FOR ALL CHECKED EXCEPTIONS
    } 
}

Cela étant dit, pour des raisons de verbosité, il serait peut-être préférable de définir une variable booléenne ou une autre variable et d'exécuter du code après le bloc try-catch.

10
Oleg Vaskevich

En pré-7 que diriez-vous:

  Boolean   caught = true;
  Exception e;
  try {
     ...
     caught = false;
  } catch (TransformerException te) {
     e = te;
  } catch (SocketException se) {
     e = se;
  } catch (IOException ie) {
     e = ie;
  }
  if (caught) {
     someCode(); // You can reference Exception e here.
  }
3
Bill S

Attrapez l'exception qui se trouve être une classe parente dans la hiérarchie des exceptions. C'est bien sûr, mauvaise pratique . Dans votre cas, l'exception parent commune se trouve être la classe Exception, et intercepter une exception qui est une instance d'Exception est en effet une pratique déconseillée. Des exceptions comme NullPointerException sont généralement des erreurs de programmation et doivent généralement être résolues en vérifiant les valeurs NULL.

0
Vineet Reynolds

Oui. Voici le moyen d'utiliser un séparateur de tuyau (|),

try
{
    .......
}    
catch
{
    catch(IllegalArgumentException | SecurityException | IllegalAccessException | NoSuchFieldException e)
}
0
Shiva