A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 马年出黑马 中级黑马   /  2014-5-3 14:27  /  1289 人查看  /  4 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 马年出黑马 于 2014-5-3 15:04 编辑

     张*奇同学成功挑逗起了我钻牛角尖的情绪,昨天看到你那个Exception问题已经1点了,本来打算睡觉,结果又想了一个小时,欲罢不能。
首先把张同学原问题帖一下:(是张图片)
现在有一点自己的想法,你们看看有没有道理:
      首先结论:前面的FileNotFoundException的确被catchIOException e)抓获了,没有显示抛出是因为在作出抛出动作前要先执行finally
解释:
      控制台显示异常信息,是JVM调用了异常对象的printStackTrace()方法,打印方法调用栈的异常信息。也就意味着JVM找不到处理此异常的catch块了,他自己处理了,而JVM自己处理异常会做两个事情:
      第一、调用异常的对象的printStackTrace()方法,打印方法调用栈的异常信息。
      第二、如果出现异常的线程为主线程,则整个程序运行终止;如果非主线程,则终止该线程,其他线程继续运行
      至此,我们知道,一旦JVM自己处理异常就意味着线程要终止,所以finally语句一定要在JVM处理异常前执行,否则将没有执行机会,也就没有了他的意义。
      至此分析原问题就明了了,前面我们catchIOException,转而抛出了RuntimeException,而这个RuntimeException我们没有其他的程序处理他了,JVM判断只能对他做第一、第二处理了,但在这之前要先来把finally做了,不巧,finally里也有个没人处理的异常,JVM就针对它执行了第一、第二,线程终止了,前面没处理的那个也没机会了(当然,我们看到如果finally执行的妥妥的,程序执行完finally后就回去处理之前那个异常了)
      这样推断下来,我们发现,如果是单线程的话,其实JVM只有一次printStackTrace()在控制台显示异常信息的机会,也就是说不管有几个没人处理的异常(也不加e.printStackTrace();语句),只有一个有在控制台露脸的机会。是不是这样呢?我还没有验证,你们觉得呢?

我的验证代码:

  1. <p><p><p style="line-height: 30px; text-indent: 2em;"></p><p style="line-height: 30px; text-indent: 2em;"></p><p style="line-height: 30px; text-indent: 2em;"></p><p style="line-height: 30px; text-indent: 2em;"></p><p style="line-height: 30px; text-indent: 2em;"></p><p style="line-height: 30px; text-indent: 2em;"></p><p style="line-height: 30px; text-indent: 2em;"></p>import java.io.*;

  2. public class Test {

  3.         static BufferedReader br=null;
  4.         static BufferedWriter bw=null;
  5.         public static void main(String[] args) throws Exception {
  6.                 try{
  7.                         BufferedReader br=new BufferedReader(new FileReader("stu.txt"));
  8.                         BufferedWriter bw=new BufferedWriter(new FileWriter("M:\\stu.txt"));//故意找了个无效目录,会抛出FileNotFoundException
  9.                         String line=null;
  10.                         while((line=br.readLine())!=null) {
  11.                                 System.out.println(line);
  12.                                 bw.write(line);
  13.                                 bw.newLine();
  14.                                 bw.flush();
  15.                         }
  16.                 }
  17.                 catch(IOException e) { //这里能抓到FileNotFoundException</p><p>                        //e.printStackTrace();  //其实加上这一句,就能从控制台看到异常信息了  
  18.                         System.out.println("zhixing");//用来验证是否抓到
  19.                         throw new FileNotFoundException("读写失败");
  20.                 }
  21.                 finally {
  22.                         try {
  23.                                 if(br!=null) {
  24.                                         br.close();
  25.                                 }
  26.                         }
  27.                         catch(IOException e) {
  28.                                 throw new NullPointerException("流关闭异常");
  29.                         }
  30.                         try {
  31. //                                if(bw!=null) //故意让这里抛出个异常
  32.                                         bw.close();
  33.                                 
  34.                         }
  35.                         catch(IOException e) {
  36.                                 throw new RuntimeException("流关闭异常");
  37.                         }
  38.                         catch(RuntimeException e) { //把NullPointerException抓过来
  39.                                 System.out.println("处理了!");//将下面一行注释掉,不抛出,FileNotFoundException("读写失败")就成功打印!
  40.                                 //throw new NullPointerException("空指向异常");//抛出了,就得JVM做处理,控制台打印了这个后线程就终止了
  41.                         }
  42.                 }
  43.         }

  44. }</p></p>
复制代码


评分

参与人数 1技术分 +1 收起 理由
轻语。 + 1

查看全部评分

4 个回复

倒序浏览
顶,沙发
回复 使用道具 举报
:L蒙蒙的
回复 使用道具 举报
火钳刘明
回复 使用道具 举报
厉害,程序员就应该有这样的精神!膜拜
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马