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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© Neverbelazy 中级黑马   /  2013-4-21 16:54  /  1641 人查看  /  7 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 Neverbelazy 于 2013-4-28 14:45 编辑

java调用OS资源是需要程序手动关闭的。在毕老师的视频第18天中,IO流完成文件的复制时要在finally中分别关闭FileWriter和FileReader流对象(此处定义为fw,fr)。
其中提到,不可以在一个try-catch模块中同时关闭两个,例如:
  1. try{
  2. fw.close();
  3. fr.close();
  4. }catch(IOException e){ //定义的异常产生提示或解决语句}
复制代码
这是因为如果fw.close()产生了异常,fr.close()就执行不到了,相当于没有关闭读取流fr的资源。
毕老师给出的解决办法是分开 来两个try-catch 块
  1. try{
  2. fw.close();
  3. }catch(IOException e){ //定义的异常产生提示或解决语}
  4. try{
  5. fr.close();
  6. }catch(IOException e){ //定义的异常产生提示或解决语}
复制代码
但是这似乎还是有问题的:比如说,如果我们将上面代码的两个catch(){}内的解决办法定义为 throw new RuntimeException(); 同样会存在造成 fr 资源没有关闭的隐患。
毕老师的视频中还提到一种解决try-catch-finally{try-catch}嵌套的解决办法,如果是样,就可以安全的关闭资源了。
  1. try{
  2. fw.close();
  3. }catch(IOException e){ throw new RuntimeException();}
  4. finally{
  5. try{
  6. fr.close();
  7. }catch(IOException e){throw new RuntimeException();}
  8. }
复制代码
这是我的一些看法,请指正。

-------------------------------------分割线------------------------
Q:我不太确定了  throw RuntimeExcetpion()后 JVM是将程序直接 停止了 还是 仍会 执行下面的代码? 请高手解答!
5.27PM更新编辑
A:已经解决: throw RuntimeException()后 程序停止,不会在执行之后的代码,但是会执行finally的代码! 所以 try-catch-finally(try-catch)模式的资源关闭是三者中最健壮的。

  1. public class RuntimeExceptionTest {

  2.         public static void main(String[] args){
  3.                 try{
  4.                         System.out.println(5/0);
  5.                 }catch(Exception e){
  6.                         System.out.println("之前的代码");
  7.                         throw new RuntimeException("catch...");        
  8.                 }
  9.                 finally{
  10.                         System.out.println("final的代码");
  11.                 }
  12.                 System.out.println("之后的代码");

  13.         }
  14.         
  15. }
复制代码

评分

参与人数 1技术分 +1 收起 理由
王怀亮 + 1

查看全部评分

7 个回复

倒序浏览
值得学习ing!
回复 使用道具 举报

  1. public class ExceptionTest {

  2.         /**
  3.          * @param args
  4.          */
  5.         public static void main(String[] args) {
  6.                 // TODO Auto-generated method stub
  7.                 try {
  8.                         throw new RuntimeException("程序正常代码异常,退出jvm。");
  9.                 } catch (Exception e) {
  10.                        
  11.                         System.out.println(e.toString());
  12.                 }
  13.                 finally {
  14.                         /**
  15.                          * 1、关闭资源放到finally代码块中,不管try代码抛出什么异常,这里的代码都会执行。
  16.                          * 2、finally代码块中前面的的语句发生异常,不影响后面的正常执行。
  17.                          * 3、从第一个关资源try看出,要关闭多个资源,一定要分开try。
  18.                          */
  19.                         try {
  20.                                 throw new RuntimeException("资源一关闭异常");
  21.                                 //System.out.println("看看我有被执行吗?");//这句话编译不通过,说明他不会被执行
  22.                         } catch (Exception e) {
  23.                                
  24.                                 System.out.println(e.toString());
  25.                         }
  26.                        
  27.                         try {
  28.                                 throw new RuntimeException("资源二关闭异常");
  29.                         } catch (Exception e) {
  30.                                
  31.                                 System.out.println(e.toString());
  32.                         }
  33.                        
  34.                         try {
  35.                                 throw new RuntimeException("资源二关闭异常");
  36.                         } catch (Exception e) {
  37.                                
  38.                                 System.out.println(e.toString());
  39.                         }
  40.                 }

  41.         }

  42. }
复制代码
执行结果:
java.lang.RuntimeException: 程序正常代码异常,退出jvm。
java.lang.RuntimeException: 资源一关闭异常
java.lang.RuntimeException: 资源二关闭异常
java.lang.RuntimeException: 资源二关闭异常

回复 使用道具 举报
我觉得从你的总结来看 ,你的理解是有点问题。如果我理解错了,请指出来。谢谢。
两个try不管是分开try...catch,还是try...catch...finally,这 两个try都在finally中。
而finally代码块中前面的的语句发生异常,不影响后面的正常执行。
我觉得楼上的代码说明了所有问题。

点评

请参看我楼下的回复  发表于 2013-4-28 14:37
回复 使用道具 举报
本帖最后由 Neverbelazy 于 2013-4-28 14:38 编辑
孙胜 发表于 2013-4-28 11:42
执行结果:
java.lang.RuntimeException: 程序正常代码异常,退出jvm。
java.lang.RuntimeException: 资源 ...

我理解你的意思,你的意思是 try{ 中的 throw new RuntimeException();} 是否会被catch; 你的这段 try-catch-finally 总结的很好!
但是我想解决的是,如果 catch(Exception e){中有 throw new RuntimeException()};

catch中抛异常也不是没有可能的,比如说,我也不知道该怎么 catch(解决)try 中的异常,那就 再抛一个吧,让jvm报runtime提示
一旦catch中抛了,finally代码执行,但是 在此finally之后的任何代码都不会被执行了,详见我原帖中最后一段验证代码
回复 使用道具 举报
Neverbelazy 发表于 2013-4-28 14:34
我理解你的意思,你的意思是 try{ 中的 throw new RuntimeException();} 是否会被catch; 你的这段 try-cat ...

哥们你太纠结了,
你想想当你关闭资源失败时,你能做什么?
其实你是处理不了这个异常的,一般情况下士要把这个异常抛给你的调用方去处理的
回复 使用道具 举报
孙胜 发表于 2013-4-28 14:43
哥们你太纠结了,
你想想当你关闭资源失败时,你能做什么?
其实你是处理不了这个异常的,一般情况下士要 ...

好吧,我确实是还考虑不清楚该怎么做才是比较 “实际” 的解决方法。我的帖子中只是想比较两种关闭资源的方法
  1. finally{ try-catch try-catch}
  2. finally{try-catch finally{try-catch}}
复制代码
哪种更加的 健壮。

如果存在 catch(){中抛 异常的情况}, 那么结论是 finally{try-catch-finally{try-catch}}的方法更好
回复 使用道具 举报
Neverbelazy 发表于 2013-4-28 14:34
我理解你的意思,你的意思是 try{ 中的 throw new RuntimeException();} 是否会被catch; 你的这段 try-cat ...

是我没有仔细看椅子上的代码。我以为他就是像你说的那样写的。
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马