java – 块catch中的丢失异常

我运行这段代码:

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");
        }

    }
}

Result:
try: 1
catch: 2
finally: 3
Exception in thread
“main” java.lang.NullPointerException
at user.main(User.java:17)

在块catch中 – ArrayIndexOutOfBoundsException,但是我们丢失了这个Exception,为什么呢?

最佳答案
来自JLS

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

If execution of the try block completes abruptly for any other reason R, then the finally block is executed. Then there is a choice:

  • If the finally block completes normally, then the try statement completes abruptly for reason R.
  • If the finally block completes abruptly for reason S, then the try statement completes abruptly for reason S (and reason R is discarded). The example…

因此,以下(从提问者的代码中真正浓缩)完成了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 / 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/finally.Can I avoid such cumbersome try/catch/finally…

转载注明原文:java – 块catch中的丢失异常 - 代码日志