为什么main方法不会从catch块中捕获未捕获的异常

时间:2011-10-17 13:51:46

标签: java exception exception-handling nullpointerexception try-catch

我在学习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块中发生的异常在哪里去了?

下面没有捕获块,不应该被主线程抛出吗?因为它没有被捕获?

1 个答案:

答案 0 :(得分:7)

该异常实际上已丢失 - 如果finally块抛出异常,则传播过程中的任何异常都变得无关紧要,而finally块的结果是新的异常。

同样,如果你在finally块中返回,那么整个try / catch / finally将永远不会抛出异常。

有关详细信息,请参阅section 14.20.2 of the Java Language Specification。特别是,像这样的各种位:

  

如果finally块因任何原因突然完成,那么try语句会因同样的原因而突然完成。