Natknąłem się na kod wyglądający mniej więcej tak:
void run() {
try {
doSomething();
} catch (Exception ex) {
System.out.println("Error: " + ex);
throw ex;
}
}
void doSomething() {
throw new RuntimeException();
}
Ten kod mnie zaskakuje, ponieważ wygląda na to, że run()
-metoda jest w stanie wyrzucić Exception
, ponieważ łapie, Exception
a następnie ponownie rzuca, ale metoda nie jest zadeklarowana do rzucenia Exception
i najwyraźniej nie musi być. Ten kod dobrze się kompiluje (przynajmniej w Javie 11).
Oczekuję , że będę musiał zadeklarować throws Exception
w run()
metodzie.
Dodatkowe informacje
W podobny sposób, jeśli doSomething
zostanie zadeklarowany jako rzut, IOException
to IOException
musi być zadeklarowany tylko w run()
metodzie, nawet jeśli Exception
zostanie złapany i ponownie rzucony.
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 ...
}
Pytanie
Java zazwyczaj lubi jasność, jaki jest powód tego zachowania? Czy zawsze tak było? Co w specyfikacji języka Java pozwala run()
metodzie nie musieć deklarować throws Exception
w powyższych fragmentach kodu? (Gdybym dodał, IntelliJ ostrzega mnie, że Exception
nigdy nie zostanie wyrzucony).
-source 1.6
flagą powoduje błąd kompilacji zgodnie z oczekiwaniami. Kompilacja z kompatybilności źródło 7 czy nie podnieść błąd kompilacji
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
- natknąłem się na przypadki, w których kompilator Eclipse był bardziej łagodny.