使用finally回收资源
当程序在try中打开了一些物理资源(数据库、网络连接、磁盘文件)时,这些物理资源都必须通过显示回收。
注意:虽然Java中有自身携带的垃圾回收机制,但是该回收机制只能回收对内存中的对象所占由的内存,对于物理资源无法回收,必须通过显示的方式进行回收。
在Java的异常处理语法中,我们知道有try块、catch块、finally块,这三块只有try块是必需的,catch块和finally块是可选的,但是二者必需选其一,或者二者同时出现。在catch块,先出现捕获子类异常,再出现捕获父类异常。finally块必需位于catch块之后。
public class FinallyTest
{
public static void main (String args[])
{
FileInputStream fis = null;
try
{
fis = new FileInputStream("a.txt");
}
catch(IOException ioe)
{
System.out.println(ioe.getMessage());
//return语句强制方法返回
return;//(1)
//使用exit退出虚拟机
//System.exit(1); //(2)
}
finally
{
//关闭磁盘文件回收资源
if(fis != null)
{
try
{
fis.close();
}
catch(IOException ioe)
{
ioe.printStackTrace();
}
}
System.out.println("执行finally块里的资源回收!");
}
}
}
分析:上述程序中在try .... catch块后有finally块,用于回收在try块中打开的物理资源。通常情况下,当程序执行到程序中的return语句时,该程序结束。但是在此程序的catch块中虽然有个return语句,但是该程序不会立即停止,他还要执行finally块里面的语句。
运行结果:
a.txt(系统找不到指定的文件。)
执行finally块里的资源回收!
分析:将(1)中的return语句注释掉,取消(2)处的注释。即运行catch块中的System.exit(1)语句来退出虚拟机。则finally里面的代码块不会被执行。
运行结果:
a.txt(系统找不到指定的文件。)
除非在try块、catch块中调用了退出虚拟机的方法。否则finally块总被执行。
通常而言,不推荐在finally快里面是用return语句和throw语句。因为一旦在finally块里使用return语句和throw语句,则try块和catch块中的return语句和throw语句将失效。
public class FinalluFlowTest
{
public static void main(String args[])throws Exception
{
boolean a =test();
System.out.println(a);
}
public static boolean tast()
{
try
{
//因为finally块里包含了return 语句,所以下面的return语句失去作用
return ture;
}
finally
{
return false;
}
}
}
运行结果:
false
分析:在执行try或者catch块时,如果遇到return或者FALSE语句,则停止运行,跳转至finally块,继续运行。
异常处理嵌套:就是在try块、catch块、或者finally块中,在出现一套完整的异常处理流程。
为了避免出现臃肿的代码,在Java7中增强了try 语句的功能,允许在try关键字后紧跟一个圆括号,圆括号可以声明、初始化一个或者多个资源(数据库连接、网络连接),try语句在该语句结束后自动关闭这些资源。
这些资源必须实现AutoCloseable或者Closeablej口。实现这两个借口就必须实现close()方法。
Closeable只能抛出IOException或其子类。
public class AutoCloseTest
{
/**
* @param args
*/
public static void main(String[] args)throws Exception
{
// TODO Auto-generated method stub
try(BufferReader br = new BufferReader(new FileReader("AutoClosetest.java"));
PrintStream ps = new PrintStream(new FileOutStream("a.txt")))
{
System.out.println(br.readLine());
ps.prinln("庄生晓梦迷蝴蝶");
}
}
}