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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

本帖最后由 黑马_许芸 于 2012-9-9 06:59 编辑

这是毕老师的一段代码。我想问如果fw.close();抛出异常的话,那下面的代码fr.close();还会执行吗?
额,其实老师都这么写了,我想应该是会执行的,只是不知道怎么测试。然后什么情况下下面的代码不会执行呢?为什么?我始终不懂这点。
  1. finally{
  2.    if (fw != null)
  3.    {
  4.     try
  5.     {
  6.      fw.close();
  7.     } catch (IOException e)
  8.     {
  9.      // TODO Auto-generated catch block
  10.      e.printStackTrace();
  11.     }
  12.    }
  13.    if (fr != null)
  14.    {
  15.     try
  16.     {
  17.      fr.close();
  18.     } catch (IOException e)
  19.     {
  20.      // TODO Auto-generated catch block
  21.      e.printStackTrace();
  22.     }
  23.    }
  24.   }
复制代码

评分

参与人数 1技术分 +1 收起 理由
创出一片辉煌 + 1 赞一个!

查看全部评分

6 个回复

倒序浏览
  • finally{
  • if (fw != null)
  • {
  • try
  • {
  • fw.close(); //这里如果抛出异常的话,那么抛出的是IOException
  • } catch (IOException e) //fw.close()抛出的异常会被捕获
  • {
  • // TODO Auto-generated catch block
  • e.printStackTrace(); //处理方式是打印出异常信息,那么后面的代码也会执行
  • }
  • }
  • if (fr != null)
  • {
  • try
  • {
  • fr.close();   //这里还是要执行的
  • } catch (IOException e)
  • {
  • // TODO Auto-generated catch block
  • e.printStackTrace();
  • }
  • }
  • }
回复 使用道具 举报
给楼主一个测试代码,可以看出finally中第二个try还是要执行的
public class ExceptionTest {
public static void main(String[] args) {
  try {
   System.out.println("hello");
  } catch (Exception e) {
   
  }
  finally{
   try {
    throw new RuntimeException("finally中的第一个try抛出异常");
   } catch (Exception e2) {
    e2.printStackTrace();
   }
   try {
    System.out.println("finally中第二个try被执行");
   } catch (Exception e2) {
   
   }
  }
}
}

评分

参与人数 1技术分 +1 收起 理由
创出一片辉煌 + 1 赞一个!

查看全部评分

回复 使用道具 举报
楼上的代码能够测试它的运行顺序,一般finally里面的语句是一定能执行的语句
但是当下面的代码时第二个try就执行不到
finally
    {
      try
      {
    throw new RuntimeException("finally中的第一个try抛出异常");
      }
      catch (Exception e2)
      {
    e2.printStackTrace();
    return;
      }
      try
      {
    System.out.println("finally中第二个try被执行");
      }
      catch (Exception e2)
      {
   
      }
    }
因为当第一个抛出异常时,catch捕捉到,处理异常,return语句表示返回
则下面的try语语句执行不到
finally
    {
      try
      {
    throw new RuntimeException("finally中的第一个try抛出异常");
      }
      catch (Exception e2)
      {
    e2.printStackTrace();
    System.exit(0);
      }
      try
      {
    System.out.println("finally中第二个try被执行");
      }
      catch (Exception e2)
      {
   
      }
    }
这种情况下也不会执行到,因为System.exit(0);表示程序运行到此,java虚拟机跳出,程序结束
try
    {
     System.out.println("hello");
    }
    catch (Exception e)
    {
    System.exit(0);
    }
    finally
    {
      try
      {
    throw new RuntimeException("finally中的第一个try抛出异常");
      }
      catch (Exception e2)
      {
    e2.printStackTrace();
      }
      try
      {
    System.out.println("finally中第二个try被执行");
      }
      catch (Exception e2)
      {
   
      }
    }
准则中情况finally里面的语句根本执行不到,因为虚拟机跳出,程序结束
所以,finally语句只有这一种情况才能停止
回复 使用道具 举报
finally{
   if (fw != null)
   {
    try
    {
     fw.close();//这句代码出现异常,catch了,那么程序就不会中断,继续执行。
    } catch (IOException e)
    {
     // TODO Auto-generated catch block
     e.printStackTrace();//上面出现异常,这里捕捉,执行处理代码,
      //System.exit(0);//如果这个代码快中出现System.exit(0),那么虚拟机退出,整个程序结束,那么下面的代码当然就不执行了。
    }
   }
   if (fr != null)
   {
    try
    {
     fr.close();
    } catch (IOException e)
    {
     // TODO Auto-generated catch block
     e.printStackTrace();
    }
   }
  }

程序出现异常,处理了,只要不是RuntimeException,那么程序不会停止,会继续执行代码,这应该也是异常机制的目的所在吧。
回复 使用道具 举报
问题已解决,谢谢大家。
回复 使用道具 举报
虽然楼主问题已解决,但还是说一点自己的想法。
楼主所列的代码在编译时肯定是不会抛出异常的,因为流的close方法的作用是关闭流释放底层资源,只要代码语法格式正确就会编译通过,简单想一想就可以明白。我想说的是fw.close();和fr.close();分别在两个不同的try{}catch(){}代码块中,是互不影响的,前一个try{}中代码发生的异常,在相应的catct(){}代码块中捕捉并执行完处理异常代码之后,还是会顺序下一个try{}catch(){}代码块。我想楼主应该是跟受这么个概念影响:在同一个try{}中,如果一条语句发生异常,则不会继续执行该语句之后的代码,注意是同一个try{}中。拿个简单代码举例:
  1. class TestException
  2. {
  3.         public static void main(String[] args)
  4.         {
  5.                 try
  6.                 {
  7.                         int[] arr = new int[]{1,2,3};
  8.                         System.out.println(arr[3]);//此处发生异常
  9.                         System.out.println("运行不到这里");
  10.                 }
  11.                 catch (Exception e)
  12.                 {
  13.                         System.out.println("catch块中的语句");
  14.                 }

  15.                 System.out.println("可以运行到这里");
  16.         }
  17. }
复制代码
把“System.out.println("可以运行到这里");”语句换成try{}catch(){}代码块即和楼主代码类似。
我记得毕老师在讲这块的时候就说过,不能把fr.close()和fw.close()放在同一个try中,如果这样,一个发生异常,另一个就执行不到,应该就是这个意思。
另外,毕老师也说过,要将相关的代码放在同一个try中,这样一条语句发生异常之后继续执行相关的代码就失去了意义,而放在一个try中则不会继续执行相关代码。所以总的来说就是,相关代码应该放在同一个try中,这样可以避免执行无效代码;无关代码要放在不同的try中(如果都发生异常),这样代码互不影响执行。
希望帮到楼组理解这个问题。

点评

说的很好,谢谢。相关代码放在同一个try中,无关代码放在不同的try中以避免相互影响,嗯,我懂了。  发表于 2012-9-9 11:25
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马