我在学习OCPJP认证的模拟考试时想出了这个例子 (来自http://www.certpal.com版本1.6考试第3部分,流程控制,问题编号8)
public class Oak
{
public static void main(String args[])
{
try
{
Integer i =null;
i.toString();
}
catch (Exception e)
{
try
{
System.out.println("One ");
Integer i =null;
i.toString();
}
catch (Exception x)
{
System.out.println("Two ");
Integer i =null;
i.toString();
}
finally
{
System.out.println("Three ");
Integer i =null;
i.toString();
}
}
finally
{
System.out.println("Four ");
}
}
}
我完全知道finally块总是会执行,除非有一个System.exit(),所以我跟踪了程序并确定它会有这样的输出
线程“main”中的两个异常java.lang.NullPointerException线程“main”中的三个异常java.lang.NullPointerException四
然而,事实证明正确的输出是(根据站点和Eclipse调试)
线程“main”java.lang.NullPointerException
中的一个二三四异常
我不理解的是,带有“两个”的catch块中发生的异常在哪里去了?
下面没有捕获块,不应该被主线程抛出吗?因为它没有被捕获?
答案 0 :(得分:7)
该异常实际上已丢失 - 如果finally块抛出异常,则传播过程中的任何异常都变得无关紧要,而finally块的结果是新的异常。
同样,如果你在finally块中返回,那么整个try / catch / finally将永远不会抛出异常。
有关详细信息,请参阅section 14.20.2 of the Java Language Specification。特别是,像这样的各种位:
如果finally块因任何原因突然完成,那么try语句会因同样的原因而突然完成。