Quand à attraper java.lang.D'erreur?


Dans quelles situations faut-il attraper java.lang.Error sur une application?

Author: Laurel, 2008-12-09

16 answers

Généralement, jamais. Cependant, vous devez parfois détecter des erreurs spécifiques.

Si vous écrivez du code framework-ish (chargement de classes tierces), il pourrait être sage d'attraper LinkageErrors (aucune def de classe trouvée, lien insatisfait, changement de classe incompatible). J'ai également vu du code 3rd-party stupide lancer des sous-classes d'erreurs, vous devrez donc les gérer non plus.

Au fait, je ne suis pas sûr qu'il ne soit pas possible de récupérer de OutOfMemory.

 90
Author: Yoni Roit, 2008-12-09 14:12:02

Jamais. Vous ne pouvez jamais être sûr que l'application est capable d'exécuter la ligne de code suivante. Si vous obtenez un OutOfMemoryError, vous avez aucune garantie que vous serez en mesure de faire quelque chose de manière fiable. Catch RuntimeException et exceptions vérifiées, mais jamais d'erreurs.

Http://pmd.sourceforge.net/rules/strictexception.html

 46
Author: tronda, 2017-05-23 12:26:20

Généralement, vous devriez toujours catch java.lang.Error et l'écrire dans un journal ou l'afficher à l'utilisateur. Je travaille à l'appui et je vois quotidiennement que les programmeurs ne peuvent pas dire ce qui s'est passé dans un programme.

Si vous avez un thread de démon, vous devez empêcher sa fin. Dans d'autres cas, votre application fonctionne correctement.

Vous ne devriez attraper java.lang.Error qu'au plus haut niveau.

Si vous regardez la liste des erreurs, vous verrez que la plupart peuvent être traités. Par exemple, un ZipError se produit sur la lecture des fichiers ZIP corrompus.

Les erreurs les plus courantes sont OutOfMemoryError et NoClassDefFoundError, qui sont dans la plupart des cas des problèmes d'exécution.

Par exemple:

int length = Integer.parseInt(xyz);
byte[] buffer = new byte[length];

Peut produire un OutOfMemoryError, mais c'est un problème d'exécution et aucune raison de mettre fin à votre programme.

NoClassDefFoundError se produisent principalement si une bibliothèque n'est pas présente ou si vous travaillez avec une autre version de Java. S'il s'agit d'une partie facultative de votre programme, vous ne devez pas mettre fin à votre programme.

Je peux donner beaucoup plus d'exemples de pourquoi c'est une bonne idée d'attraper Throwable au plus haut niveau et produire un message d'erreur utile.

 15
Author: Horcrux7, 2015-06-11 14:40:14

Dans un environnement multithread, vous voulez le plus souvent l'attraper! Lorsque vous l'attrapez, connectez-le et terminez toute l'application! Si vous ne le faites pas, un thread qui pourrait faire une partie cruciale serait mort, et le reste de l'application pensera que tout est normal. De cela, de nombreuses situations indésirables peuvent se produire. Un plus petit problème est que vous ne seriez pas en mesure de trouver facilement la racine du problème, si d'autres threads commencent à lancer des exceptions à cause d'un thread non travailler.

Par exemple, la boucle devrait généralement être:

try {
   while (shouldRun()) {
       doSomething();
   }
}
catch (Throwable t) {
   log(t);
   stop();
   System.exit(1);
}

Même dans certains cas, vous voudriez gérer différentes erreurs différemment, par exemple, sur OutOfMemoryError, vous seriez en mesure de fermer l'application régulièrement (même peut-être libérer de la mémoire, et continuer), sur d'autres, il n'y a pas grand-chose que vous pouvez faire.

 13
Author: Sarmun, 2009-03-08 11:45:55

Très rarement.

Je dirais seulement au niveau supérieur d'un thread afin de TENTER d'émettre un message avec la raison de la mort d'un thread.

Si vous êtes dans un cadre qui fait ce genre de chose pour vous, laissez faire le cadre.

 7
Author: Darron, 2008-12-09 14:15:27

Presque jamais. Les erreurs sont conçues pour être des problèmes sur lesquels les applications ne peuvent généralement rien faire. La seule exception pourrait être de gérer la présentation de l'erreur, mais même cela pourrait ne pas se passer comme prévu en fonction de l'erreur.

 6
Author: nicerobot, 2008-12-09 13:59:06

Un Error habituellement ne devrait pas être pris, comme indique une situation anormale qui ne devrait jamais se produire.

De la spécification de l'API Java pour le Error classe:

Un Error est une sous-classe de Throwable cela indique de graves problèmes qu'un application raisonnable ne devrait pas essayer attraper. La plupart de ces erreurs sont conditions anormales. [...]

Une méthode n'est pas requise pour déclarer sa clause jette toutes les sous-classes de Erreur qui pourrait être lancée pendant le exécution de la méthode mais pas pris, puisque ces erreurs sont conditions anormales qui ne devraient jamais produire.

Comme le mentionne la spécification, un Error n'est lancé que dans des circonstances qui sont Il est probable que, lorsqu'un Error se produit, l'application peut faire très peu de choses et, dans certaines circonstances, la machine virtuelle Java elle-même peut être dans un état instable (tel que VirtualMachineError)

Bien qu'un Error est un sous-classe de Throwable ce qui signifie qu'il peut être attrapé par une clause try-catch, mais ce n'est probablement pas vraiment nécessaire, car l'application sera dans un état anormal lorsqu'un Error est lancé par la JVM.

Il y a aussi une courte section sur ce sujet dans la section 11.5 La Hiérarchie des exceptionsde la Spécification du langage Java , 2nd Edition.

 6
Author: coobird, 2008-12-09 14:37:32

Si vous êtes assez fou pour créer un nouveau framework de test unitaire, votre coureur de test devra probablement attraper java.lang.AssertionError lancée par tous les cas de test.

Sinon, voir d'autres réponses.

 6
Author: noahlz, 2008-12-10 20:44:45

Et il y a quelques autres cas où si vous attrapez une erreur, vous je dois le repenser. Par exemple ThreadDeath ne devrait jamais être attrapé, cela peut causer un gros problème est que vous l'attrapez dans un environnement contenu (par exemple. un serveur d'applications):

Une application doit attraper les instances de cette classe que si elle doit nettoyer après avoir été terminé de manière asynchrone. Si ThreadDeath est capturé par une méthode, il est important qu'il soit repensé pour que le thread meurt en fait.

 5
Author: Guillaume, 2008-12-09 14:09:10

Très, très rarement.

Je ne l'ai fait que pour un cas connu très très spécifique. Par exemple, java.lang.UnsatisfiedLinkError pourrait être lancé si deux independence ClassLoader chargent la même DLL. (Je suis d'accord que je devrais déplacer le POT vers un classloader partagé)

Mais le cas le plus courant est que vous aviez besoin de vous connecter afin de savoir ce qui s'est passé lorsque l'utilisateur vient se plaindre. Vous voulez un message ou une fenêtre contextuelle à l'utilisateur, plutôt que silencieusement mort.

Même programmeur en C / C++, ils pop une erreur et dire quelque chose que les gens ne comprennent pas avant sa sortie (par exemple, une défaillance de la mémoire).

 4
Author: Dennis C, 2008-12-09 14:28:55

Dans une application Android, j'attrape un java.lang.Exception verifyerror. Une bibliothèque que j'utilise ne fonctionnera pas dans les appareils avec une ancienne version du système d'exploitation et le code de la bibliothèque générera une telle erreur. Je pourrais bien sûr éviter l'erreur en vérifiant la version du système d'exploitation au moment de l'exécution, mais:

  • Le plus ancien SDK pris en charge peut changer à l'avenir pour la bibliothèque spécifique
  • Le bloc d'erreur try-catch fait partie d'un mécanisme de retour en arrière plus important. Certains dispositifs spécifiques, bien qu'ils soient censé prendre en charge la bibliothèque, lancez des exceptions. J'attrape VerifyError et toutes les exceptions pour utiliser une solution de repli.
 3
Author: kgiannakakis, 2013-03-14 06:17:07

C'est assez pratique pour attraper java.lang.AssertionError dans un environnement de test...

 3
Author: Jono, 2013-11-27 01:53:46

Idéalement, nous ne devrions pas gérer / attraper les erreurs. Mais il peut y avoir des cas où nous devons le faire, en fonction de l'exigence du cadre ou de l'application. Disons que j'ai un démon d'analyseur XML qui implémente DOM Parser qui consomme plus de mémoire. S'il y a une exigence comme Parser thread ne devrait pas être mort quand il obtient OutOfMemoryError, à la place, il devrait le gérer et envoyer un message/mail à l'administrateur de l'application/framework.

 2
Author: user3510364, 2014-05-05 18:22:03

Idéalement, nous ne devrions jamais attraper d'erreur dans notre application Java car il s'agit d'une condition anormale. L'application serait dans un état anormal et pourrait entraîner un carshing ou donner un résultat sérieusement erroné.

 1
Author: Vivek, 2011-01-26 06:23:27

Il peut être approprié de détecter une erreur dans les tests unitaires qui vérifient qu'une assertion est faite. Si quelqu'un désactive les assertions ou supprime l'assertion que vous voulez savoir

 1
Author: Chanoch, 2012-08-19 20:35:49

Il y a une erreur lorsque la JVM ne fonctionne plus comme prévu ou est sur le point de le faire. Si vous attrapez une erreur, il n'y a aucune garantie que le bloc catch fonctionnera, et encore moins qu'il fonctionnera jusqu'à la fin.

Cela dépendra également de l'ordinateur en cours d'exécution, de l'état actuel de la mémoire, il n'y a donc aucun moyen de tester, d'essayer et de faire de votre mieux. Vous n'aurez qu'une risqués résultat.

Vous rétrograderez également la lisibilité de votre code.

 1
Author: Nicolas Zozol, 2013-04-23 16:50:35