黑马程序员技术交流社区
标题:
毕老师的视频——在finally中关闭IO流
[打印本页]
作者:
黑马_许芸
时间:
2012-9-8 19:29
标题:
毕老师的视频——在finally中关闭IO流
本帖最后由 黑马_许芸 于 2012-9-9 06:59 编辑
这是毕老师的一段代码。我想问如果fw.close();抛出异常的话,那下面的代码fr.close();还会执行吗?
额,其实老师都这么写了,我想应该是会执行的,只是不知道怎么测试。然后什么情况下下面的代码不会执行呢?为什么?我始终不懂这点。
finally{
if (fw != null)
{
try
{
fw.close();
} catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if (fr != null)
{
try
{
fr.close();
} catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
复制代码
作者:
周兴华
时间:
2012-9-8 20:05
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();
}
}
}
作者:
周兴华
时间:
2012-9-8 20:17
给楼主一个测试代码,可以看出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) {
}
}
}
}
作者:
吴通
时间:
2012-9-8 21:40
楼上的代码能够测试它的运行顺序,一般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语句只有这一种情况才能停止
作者:
zhaosenyang
时间:
2012-9-8 23:28
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,那么程序不会停止,会继续执行代码,这应该也是异常机制的目的所在吧。
作者:
黑马_许芸
时间:
2012-9-9 06:58
问题已解决,谢谢大家。
作者:
李炜
时间:
2012-9-9 10:22
虽然楼主问题已解决,但还是说一点自己的想法。
楼主所列的代码在编译时肯定是不会抛出异常的,因为流的close方法的作用是关闭流释放底层资源,只要代码语法格式正确就会编译通过,简单想一想就可以明白。我想说的是fw.close();和fr.close();分别在两个不同的try{}catch(){}代码块中,是互不影响的,前一个try{}中代码发生的异常,在相应的catct(){}代码块中捕捉并执行完处理异常代码之后,还是会顺序下一个try{}catch(){}代码块。我想楼主应该是跟受这么个概念影响:
在同一个try{}中,如果一条语句发生异常,则不会继续执行该语句之后的代码,注意是同一个try{}中
。拿个简单代码举例:
class TestException
{
public static void main(String[] args)
{
try
{
int[] arr = new int[]{1,2,3};
System.out.println(arr[3]);//此处发生异常
System.out.println("运行不到这里");
}
catch (Exception e)
{
System.out.println("catch块中的语句");
}
System.out.println("可以运行到这里");
}
}
复制代码
把“System.out.println("可以运行到这里");”语句换成try{}catch(){}代码块即和楼主代码类似。
我记得毕老师在讲这块的时候就说过,不能把fr.close()和fw.close()放在同一个try中,如果这样,一个发生异常,另一个就执行不到,应该就是这个意思。
另外,毕老师也说过,要将相关的代码放在同一个try中,这样一条语句发生异常之后继续执行相关的代码就失去了意义,而放在一个try中则不会继续执行相关代码。所以总的来说就是,相关代码应该放在同一个try中,这样可以避免执行无效代码;无关代码要放在不同的try中(如果都发生异常),这样代码互不影响执行。
希望帮到楼组理解这个问题。
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2