try {
throw new RuntimeException();
} catch (Exception e) {
  System.out.println("catch");
throw new RuntimeException();  
} finally {
 System.out.println("finally");
}
异常处理中,有finally的话都会最后执行finally中的语句块,执行结果为
catch
    finally
    Exception in thread "main" java.lang.RuntimeException at FileMapper.main(FileMapper.java:26)
    
    从结果看到其实是先执行了catch中的语句块,就是说先执行了throw new RuntimeException();
    一般情况下没有 finally的话,程序就直接中断了。jvm是怎么保证如果有finally的话,先执行一下finally中的语句再抛出异常呢?
    因为看输出,其实throw new RuntimeException();  是在前面执行的。

解决方案 »

  1.   

    throw new RuntimeException();表示将RuntimeException抛到出,不在这个程序块中处理。
    finally是在try语句中最后执行。
    你的代码的意思是。
    在try的时候抛出一个RuntimeException(既然抛出了,在try里就不做处理),然后try里的代码执行完了,接着执行finally中的代码,这个try语句就彻底执行完了。
    接着该执行try以外的代码了,发现一个RuntimeException没有处理,故报了异常Exception in thread "main" java.lang.RuntimeException at FileMapper.main(FileMapper.java:26)
      

  2.   

    异常是一定要处理的, 你throw new RuntimeException()会将异常向上抛, 你没有处理, jvm会对这个异常按照默认的方式进行处理, 也就是把异常信息用标准错误输出打印出来, 也就是System.err这个流.直到处理完这个异常之后, 它才继续向下执行, 这个是单线程的, 所以, 始终顺序是try执行, 有异常了, 进异常处理分支, 这里不处理异常, 就交给上层处理, 直到处理完流程, 去执行finally.
      

  3.   

    谢谢楼上的两位。可能是我没有表达清楚意思,我的意思是:
    catch语句块中throw new RuntimeException()的时候,为啥没有第一时间吧异常跑出去,而是执行完了finally 中的代码 再抛出。如果先执行了finally 中代码再执行catch中的代码,这样就好理解了。但是从打印出的东西看,又不是这样。
      

  4.   

    靠输出结果来判断执行顺序是行不通的。我这边执行的结果正好和你相反。先显示异常信息,再输出catch和finally。原因是:java有两个标准输出:System.out和System.err,普通信息由System.out输出,异常信息由System.err输出。它们是由异步的两个线程控制的,所以它们输出的先后顺序是不确定的。要精确地跟踪程序状态,请使用debug工具,而不要依赖输出结果。