Je suis tombé sur un code ressemblant à ceci:
void run() {
try {
doSomething();
} catch (Exception ex) {
System.out.println("Error: " + ex);
throw ex;
}
}
void doSomething() {
throw new RuntimeException();
}
Ce code me surprend car il semble que la run()
méthode-soit capable de lancer un Exception
, car il l'attrape Exception
puis le rejette, mais la méthode n'est pas déclarée pour lancer Exception
et n'a apparemment pas besoin de l'être. Ce code se compile très bien (en Java 11 au moins).
Je m'attendrais à devoir déclarer throws Exception
dans la run()
méthode.
Informations supplémentaires
De la même manière, si doSomething
est déclaré pour lancer, IOException
il suffit IOException
de le déclarer dans la run()
méthode -même s'il Exception
est capturé et renvoyé.
void run() throws IOException {
try {
doSomething();
} catch (Exception ex) {
System.out.println("Error: " + ex);
throw ex;
}
}
void doSomething() throws IOException {
// ... whatever code you may want ...
}
Question
Java aime généralement la clarté, quelle est la raison de ce comportement? A-t-il toujours été comme ça? Qu'est-ce qui, dans la spécification du langage Java, permet à la run()
méthode de ne pas avoir à déclarer throws Exception
dans les extraits de code ci-dessus? (Si je voudrais l'ajouter, IntelliJ m'avertit qu'il Exception
n'est jamais jeté).
-source 1.6
indicateur soulève une erreur de compilation comme prévu. La compilation avec la compatibilité avec la source 7 ne soulève pas l'erreur de compilation
In detail, in Java SE 7 and later, when you declare one or more exception types in a catch clause, and rethrow the exception handled by this catch block, the compiler verifies that the type of the rethrown exception meets the following conditions : 1. 1. The try block is able to throw it. 2. There are no other preceding catch blocks that can handle it. 3. It is a subtype or supertype of one of the catch clause's exception parameters.
javac
- j'ai rencontré des cas où le compilateur Eclipse était plus indulgent.