小谈JAVA异常

来源:互联网 发布:删除json数组指定元素 编辑:程序博客网 时间:2024/05/16 08:35

今天看了篇博客点击打开链接,是关于java异常的,中间有段java的代码,如下:

public class TestException {      public TestException() {      }        boolean testEx() throws Exception {          boolean ret = true;          try {              ret = testEx1();          } catch (Exception e) {              System.out.println("testEx, catch exception");              ret = false;              throw e;          } finally {              System.out.println("testEx, finally; return value=" + ret);              return ret;          }      }        boolean testEx1() throws Exception {          boolean ret = true;          try {              ret = testEx2();              if (!ret) {                  return false;              }              System.out.println("testEx1, at the end of try");              return ret;          } catch (Exception e) {              System.out.println("testEx1, catch exception");              ret = false;              throw e;          } finally {              System.out.println("testEx1, finally; return value=" + ret);              return ret;          }      }        boolean testEx2() throws Exception {          boolean ret = true;          try {              int b = 12;              int c;              for (int i = 2; i >= -2; i--) {                  c = b / i;                  System.out.println("i=" + i);              }              return true;          } catch (Exception e) {              System.out.println("testEx2, catch exception");              ret = false;              throw e;          } finally {              System.out.println("testEx2, finally; return value=" + ret);              return ret;          }      }        public static void main(String[] args) {          TestException testException1 = new TestException();          try {              testException1.testEx();          } catch (Exception e) {              e.printStackTrace();          }      }  }
运行结果如下

i=2i=1testEx2, catch exceptiontestEx2, finally; return value=falsetestEx1, finally; return value=falsetestEx, finally; return value=false
我要从java编程规范和生成的class文件的字节码来进行分析。
在java se 7编程规范中如下表述:

If a finally clause is executed because of abrupt completion of a try block and the finally clause itself completes abruptly, then the reason for the abrupt completion of the try block is discarded and the new reason for abrupt completion is propagated from there.

大概意思就是如果finally语句因为try语句块突然完成而执行并且finally语句自身突然完成,那么try语句块突然完成的原因就会被丢弃,并且从那里传播新的突然完成的原因。

结合代码就知道finally语句块中的return操作就使try语句块突然完成的原因被丢弃。

接下来分析下生成的字节码,需要先简化下testEx2的代码,如下:

boolean testEx2() throws Exception {          try {              throw new Exception();         } catch (Exception e) {              throw e;          } finally {              return false;          }      }
编译后的字节码如下:

boolean testEx2() throws java.lang.Exception;    Code:       0: new           #11                 // class java/lang/Exception       3: dup                  4: invokespecial #17                 // Method java/lang/Exception."<init>":()V       7: athrow               8: astore_1             9: aload_1             10: athrow              11: astore_2            12: iconst_0            13: ireturn           Exception table:       from    to  target type           0     8     8   Class java/lang/Exception           0    12    11   any
正常情况下排除任何异常后都将会被异常表中的any项捕获,执行完finally后,会执行athrow指令将异常抛出。在finally中使用return的时候,athrow指令不会被执行,返回了false。



0 0
原创粉丝点击