使用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或其子类。
AutoCloseable接口里的close()方法抛出Exception。可以声明抛出任何异常。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("庄生晓梦迷蝴蝶"); } } }
