块捕获中的丢失异常

时间:2010-10-17 18:34:27

标签: java exception try-catch finally

我运行此代码:

public class User {

    public static void main(String args[]) {
        int array[] = new int[10];
        int i = 1;
        try {
            System.out.println("try: " + i++);
            System.out.println(array[10]);
            System.out.println("try");
        } catch (Exception e) {
            System.out.println("catch: " + i++);
            System.out.println(array[10]);
            System.out.println("catch");
        } finally {
            System.out.println("finally: " + i++);
            Object o = null;
            o.hashCode();
            System.out.println("finally");
        }

    }
}
  

结果:
试试:1
抓住:2
  最后:3
在线程中的异常   “main”java.lang.NullPointerException           在user.main(User.java:17)

in block catch - ArrayIndexOutOfBoundsException,但是我们丢失了这个Exception,为什么?

3 个答案:

答案 0 :(得分:7)

来自JLS

您可以在JLS,Blocks and Statements,“14.19.2执行try-catch-finally”一节中阅读此内容。我引用,

    如果try块的执行由于任何其他原因R突然完成,则执行finally块。然后有一个选择:
  • 如果finally块正常完成,则try语句突然完成,原因是R。
  •      
  • 如果finally块由于原因S而突然完成,则try语句突然完成,原因为S(并且原因R被丢弃)。例子......

因此,以下(从提问者的代码中真正浓缩)完成了NPE,而不是ExceptionTest抛出。

class Phinally
{
  static class ExceptionTest extends Exception
  { public ExceptionTest(String message) { super(message); }  }

  public static void main(String[] args) throws ExceptionTest
  {
    try {
      System.out.println("Foo.");
      throw new ExceptionTest("throw from try"); 
    } finally {
      throw new NullPointerException("throw from finally");
    }    
  }
}

带有资源/ ARM块的try侧边栏

在一些常见情况下,特别是在管理资源,需要嵌套的try / catch / finally块以及嵌套在finally块内时,很难对此进行推理项目COIN中“尝试使用资源”功能的原因(很快将“集成到Java中”),您可以阅读more about here

这是花费时间运行静态分析器(如PMD,找到并complains about this type of confusion的许多理由之一 - 尽管它可能无法捕捉到代码中的情况,我是不确定。

静态检查

跟进@stacktrace的评论:我通过PMD和FindBugs运行了相关代码,尝试了以下两种方法:

finally { throw NullPointerException("Foo"); }

finally { Object o = null; System.out.println(o.toString()); }

对于前者,PMD注意到并抱怨从finally子句抛出异常。 FindBugs根本没有抱怨。对于后者,PMD抱怨了几件但没有任何关系(“LocalVariableCouldBeFinal”,“StringToString”和“UselessOperationOnImmutable”)。然而,FindBugs注意到并且抱怨了一个空取消引用。故事的道德启示?运行PMD和FindBugs!

相关

与SO相关:Swallowing exception thrown in catch/finallyCan I avoid such cumbersome try/catch/finally...

答案 1 :(得分:3)

你刚刚偶然发现了Java的一个奇怪特性,如果finally块没有正确终止,它会隐藏以前抛出的任何异常。

这是设计上的,这不是一个错误。

答案 2 :(得分:1)

您在try { } catch { }块内未发生异常,因此没有catch { }finally { }处理。