Pourquoi certaines exceptions dans Java ne sont pas interceptées par catch (Exception ex)
? Ce code échoue complètement avec une exception non gérée. (Java version 1.4).
public static void main(String[] args) {
try {
//Code ...
} catch (Exception ex) {
System.err.println("Caught Exception");
ex.printStackTrace();
exitCode = app.FAILURE_EXIT_CODE;
}
finally {
app.shutdown();
}
System.exit(exitCode);
}
J'ai un Exception in thread "main" Java.lang.NoSuchMethodError
Mais ça marche
public static void main(String[] args) {
int exitCode = app.SUCCESS_EXIT_CODE;
try {
//Code ...
} catch (Java.lang.NoSuchMethodError mex){
System.err.println("Caught NoSuchMethodError");
mex.printStackTrace();
exitCode = app.FAILURE_EXIT_CODE;
} catch (Exception ex) {
System.err.println("Caught Exception");
ex.printStackTrace();
exitCode = app.FAILURE_EXIT_CODE;
}
finally {
app.shutdown();
}
System.exit(exitCode);
}
Je reçois Caught NoSuchMethodError Java.lang.NoSuchMethodError:
Je pensais que la capture des exceptions intercepterait toutes les exceptions? Comment puis-je intercepter toutes les exceptions en java?
Parce que certaines exceptions ne dérivent pas de Exception
- par exemple Throwable
et Error
.
Fondamentalement, la hiérarchie des types est la suivante:
Object
|
Throwable
/ \
Exception Error
Seules Throwables
et les classes dérivées peuvent être lancées, donc si vous attrapez Throwable
, cela va vraiment tout attraper.
Throwable
, Exception
et toute exception dérivant de Exception
autre que celles dérivées de RuntimeException
comptent comme exceptions vérifiées - ce sont ceux que vous devez déclarer que vous lancerez ou attraperez si vous appelez quelque chose qui les lance.
Tout compte fait, la hiérarchie des exceptions Java Java est un peu en désordre ...
Error
s ne sont pas Exception
s.
La classe Exception et ses sous-classes sont une forme de Throwable qui indique les conditions qu'une application raisonnable peut vouloir attraper.
- JavaDoc pour Java.lang.Exception
Une erreur est une sous-classe de Throwable qui indique de graves problèmes qu'une application raisonnable ne devrait pas essayer d'attraper.
- JavaDoc pour Java.lang.Error
Il y a certaines erreurs que vous voudrez peut-être intercepter, telles que ThreadDeath . ThreadDeath est classé comme une erreur, comme expliqué ci-dessous
La classe ThreadDeath est spécifiquement une sous-classe d'Erreur plutôt que d'Exception, même s'il s'agit d'une "occurrence normale", car de nombreuses applications interceptent toutes les occurrences d'Exception, puis ignorent l'exception.
Cependant, étant donné que la méthode stop () de Thread est désormais obsolète, vous ne devez pas l'utiliser et vous ne devriez donc jamais voir ThreadDeath.
L'exception n'est qu'un type de Throwable; NoSuchMethodError n'est pas une exception, mais une erreur, qui est un autre type de Throwable.
Vous pouvez attraper Throwable
. L'erreur et l'exception s'étendent Throwable
.
voir Throwable JavaDoc :
La classe Throwable est la superclasse de toutes les erreurs et exceptions dans le langage Java.
Comme d'autres affiches l'ont souligné, tous les objets jetables ne sont pas des sous-classes de Exception
. Cependant, dans la plupart des cas, il n'est pas judicieux d'attraper Error
ou Throwable
, car ces conditions incluent des conditions d'erreur très graves qui ne peuvent pas être facilement récupérées. Votre code de récupération peut simplement aggraver les choses.
Éliminons d'abord une confusion sémantique malheureuse dans cette discussion. Il y a le Java.lang.Exception
classe que nous pouvons simplement appeler Exception avec un "E" majuscule. Ensuite, vous avez une exception avec un "e" minuscule qui est une fonction de langue. Vous pouvez voir la version minuscule dans la documentation pour la classe Throwable
:
Aux fins de la vérification des exceptions au moment de la compilation, Throwable et toute sous-classe de Throwable qui n'est pas également une sous-classe de RuntimeException ou Error sont considérées comme des exceptions vérifiées.
Pour moi, il est plus facile de penser à la réponse à cette question comme des exceptions vérifiées et non contrôlées (minuscule e). Les exceptions cochées doivent être prises en compte lors de la compilation, contrairement aux exceptions non cochées. Exception (E majuscule) et ses sous-classes sont des exceptions vérifiées, ce qui signifie que vous devez soit intercepter toute exception pouvant être levée par votre code, soit déclarer les exceptions que votre méthode pourrait lancer (si elle n'est pas interceptée).
L'erreur et ses sous-classes sont des exceptions non contrôlées, ce qui signifie que votre code n'a pas à intercepter les erreurs qui pourraient être levées, ni à déclarer que vous lancez ces erreurs. RunTimeException et ses sous-classes sont également des exceptions non vérifiées, malgré leur emplacement dans la hiérarchie des classes.
Considérez le code suivant:
void test() {
int a = 1, b = 0, c = a / b;
}
Lorsqu'il est exécuté, le code ci-dessus produira un Java.lang.ArithmeticException
. Cela se compilera sans aucune erreur, même si une exception est levée et que le code ne capture pas l'exception ArithmeticException ni ne déclare qu'il lève cette exception. C'est l'essence des exceptions non contrôlées.
Considérez l'emplacement de ArithmeticException
dans la hiérarchie des classes, en particulier le fait qu'il s'agit d'une sous-classe de Java.lang.Exception. Ici, vous avez une exception qui dérive de Java.lang.Exception, mais comme il s'agit également d'une sous-classe de Java.lang.RuntimeException, il s'agit d'une exception non vérifiée, vous n'avez donc pas à l'attraper.
Java.lang.Object
Java.lang.Throwable
Java.lang.Exception
Java.lang.RuntimeException
Java.lang.ArithmeticException
Si vous voulez attraper tout ce qui pourrait être jeté, attrapez un Throwable. Cependant, ce n'est peut-être pas la chose la plus sûre à faire car certains de ces Throwables peuvent être des conditions d'exécution fatales qui ne devraient peut-être pas être détectées. Ou si vous attrapez Throwable, vous voudrez peut-être relancer Throwables que vous ne pouvez pas gérer. Ça dépend du contexte.
Comme le soulignent les deux autres articles, catch (Exception e) ne fonctionnera que pour les exceptions qui dérivent de Exception . Cependant, si vous regardez la hiérarchie de l'arborescence, vous remarquerez qu'une exception si Throwable . Throwable est également la classe de base pour Error . Ainsi, dans le cas de NoSuchMethodError, il s'agit d'une erreur et non d'une exception. Remarquez la convention de dénomination * Erreur vs. * Exception (comme dans IOException, par exemple).