Я натрапив на код, виглядаючи приблизно так:
void run() {
try {
doSomething();
} catch (Exception ex) {
System.out.println("Error: " + ex);
throw ex;
}
}
void doSomething() {
throw new RuntimeException();
}
Цей код мене дивує, оскільки схоже, що run()-метод здатний кинути Exception, оскільки він ловить, Exceptionа потім перезавантажує його, але метод не оголошується кинутим Exceptionі, мабуть, не потрібно. Цей код складається просто чудово (як мінімум на Java 11).
Моє сподівання було б, що мені доведеться заявити throws Exceptionв run()-методі.
Додаткова інформація
Аналогічним чином, якщо doSomethingоголошено кидок, IOExceptionто IOExceptionйого потрібно оголосити лише у run()-методі, навіть незважаючи на те, що Exceptionйого спіймали та повторно скинули.
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 ...
}
Питання
Яві зазвичай подобається ясність, в чому причина такої поведінки? Це завжди було так? Що в специфікації мови Java дозволяє run()методу не потрібно оголошувати throws Exceptionу фрагментах коду вище? (Якщо я додам, IntelliJ попереджає мене, що Exceptionніколи не кидається).
-source 1.6прапором викликає помилку компіляції, як очікувалося. Компіляція із сумісністю із джерелами 7 не призводить до помилки компіляції
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- я стикався з випадками, коли компілятор Eclipse був більш м'яким.