Я ожидаю, что следующий код поднимет ошибку времени компиляции на throw t;
, потому что main
не объявляется throw Throwable
, но он успешно компилируется (в Java 1.7.0_45) и производит вывод вы ожидали бы, если бы эта ошибка компиляции была исправлена.
public class Test {
public static void main(String[] args) {
try {
throw new NullPointerException();
} catch(Throwable t) {
System.out.println("Caught "+t);
throw t;
}
}
}
Он также компилируется, если Throwable
изменен на Exception
.
Это не скомпилируется, как ожидалось:
public class Test {
public static void main(String[] args) {
try {
throw new NullPointerException();
} catch(Throwable t) {
Throwable t2 = t;
System.out.println("Caught "+t2);
throw t2;
}
}
}
Это компилируется:
public class Test {
public static void main(String[] args) {
try {
throwsRuntimeException();
} catch(Throwable t) {
System.out.println("Caught "+t);
throw t;
}
}
public static void throwsRuntimeException() {
throw new NullPointerException();
}
}
Это не означает:
public class Test {
public static void main(String[] args) {
try {
throwsCheckedException();
} catch(Throwable t) {
System.out.println("Caught "+t);
throw t;
}
}
public static void throwsCheckedException() {
throw new java.io.IOException();
}
}
Это также компилируется:
public class Test {
public static void main(String[] args) throws java.io.IOException {
try {
throwsIOException();
} catch(Throwable t) {
System.out.println("Caught "+t);
throw t;
}
}
public static void throwsIOException() throws java.io.IOException {
throw new java.io.IOException();
}
}
Более сложный пример - проверенное исключение ловутся внешним блоком catch, вместо того, чтобы быть объявленным броском. Это компилируется:
public class Test {
public static void main(String[] args) {
try {
try {
throwsIOException();
} catch(Throwable t) {
System.out.println("Caught "+t);
throw t;
}
} catch(java.io.IOException e) {
System.out.println("Caught IOException (outer block)");
}
}
public static void throwsIOException() throws java.io.IOException {
throw new java.io.IOException();
}
}
Таким образом, кажется, что есть специальный случай, позволяющий реконструировать исключения, когда компилятор может определить, что пойманное исключение всегда является законным для повторного броска. Это верно? Где это указано в JLS? Существуют ли какие-либо другие неясные угловые случаи, подобные этому?