今天我在Java中遇到了一个奇怪的场景。我在我的方法中有一个try..catch块,它没有任何throws子句,我能够抛出catch块中捕获的异常对象。 它是Exception类的一个对象,因此它不是一个未经检查的异常。此外,如果出现异常,它不会打印堆栈跟踪,而只会吞下异常。
以下是我的代码示例
public class ExceptionTest {
public void test() {
try
{
// Some code which may throw exception.
}
catch(Exception ex)
{
// Compiler should ask me to have a *throws Exception* in the signature, when I am throwing an exception object.
throw ex;
}
}
}
但是,如果我抛出一个新的异常对象而不是catch异常对象,编译器会要求我在方法签名中有一个throws子句。
N.B:我在Java 7或8中运行时遇到这种情况。
我想知道,抛出的物体到哪里去了?有任何想法的人请...
答案 0 :(得分:13)
如果try
块中的代码无法抛出任何已检查的异常,您将看到此信息。此时,编译器知道catch
块捕获的唯一类型的异常必须是未经检查的异常,因此可以重新抛出它。请注意,如果您在ex
块中为catch
分配了不同的值,则编译器将无法再获得该保证。目前,ex
实际上是最终的。
如果您尝试调用声明在try
块中抛出已检查异常的内容,则代码将无法按预期进行编译。
例如:
public class ExceptionTest {
public void test() {
try {
foo();
} catch(Exception ex) {
throw ex;
}
}
public void foo() throws java.io.IOException {
}
}
给出错误:
ExceptionTest.java:12: error: unreported exception IOException; must be caught or declared to be thrown
throw ex;
^
关于异常“去”的地方 - 如果try块中的代码抛出未经检查的异常,它将正常传播。试试这个:
public class ExceptionTest {
public static void main(String[] args) {
test();
}
public static void test() {
try {
String x = null;
x.length();
} catch(Exception ex) {
throw ex;
}
}
}
运行它会按预期提供以下输出:
Exception in thread "main" java.lang.NullPointerException
at ExceptionTest.test(ExceptionTest.java:10)
at ExceptionTest.main(ExceptionTest.java:4)
JLS 11.2.2记录了语句可以抛出的异常 - 只有在没有可以抛出的已检查异常时才会编译代码。