【发布时间】:2014-05-10 13:27:33
【问题描述】:
我希望下面的代码会在 throw t; 上引发编译时错误,因为 main 未声明为抛出 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 在哪里指定?是否还有其他类似这样的晦涩的极端案例?
【问题讨论】:
标签: java