web-dev-qa-db-fra.com

Java exception non interceptée

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?

44
C. Ross

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 Exceptionautre 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 ...

124
Jon Skeet

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.

- JavaDoc pour ThreadDeath

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.

6
Powerlord

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.

4
Carl Manaster

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.

3
akf

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.

1
Simon Nickerson

É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.

0
Danger

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).

0
JasCav