有时候,程序在try块里打开了一些物理资源(例如数据库连接 、网络连接和磁盘文件等),这些物理资源都必须显示回收,因为Java的垃圾回收机制不会回收任何物力资源,垃圾回收机制只能回收堆内存中对象所占用的内存。
为了保证一定能回收try块中打开的物理资源,异常处理机制提供了finally块。不管try块中的代码是否出现异常,也不管哪个catch块被执行,finally块总会被执行。Java异常处理的完整语法结构如下:
try
{
//业务代码
...
}
catch(SubException e)
{
//异常处理块1
...
}
catch(SubException2 e)
{
//异常处理块2
...
}
...
finally
{
//资源回收
}
异常处理语法结构中:只有try块是必须的,也就是说如果没有try块,则不能有后面的catch块和finally块;
catch块和finally块都是可选的,但catch和finally块至少出现其中之一,也可以同时出现;
可以有多个catch块,捕获父类异常的catch块必须位于捕获子类异常的后面;
但不能只有try块,既没有catch块,也没有finally块;
多个catch块必须位于try块之后,finally块必须位于所以catch块之后。
总之:catch块和finally块是与try块相伴相生的,没有try块,就不能有catch块或者finally块;
有了try块,就必须有catch块或者finally块之一,也可以两者同时出现。
看下面的程序:
import java.io.FileInputStream;
import java.io.IOException;
public class TestFinally
{
public static void main(String[] args)
{
FileInputStream fis=null;
try
{
fis=new FileInputStream("a.txt");
}
catch (IOException ioe)
{
System.out.println(ioe.getMessage());
return; // ①//System.exit(1); // ②
}
finally
{
if(fis!=null)
{
try
{
fis.close();
}
catch (IOException ioe)
{
ioe.printStackTrace();}
}System.out.println("程序已经执行了finally里的资源回收!");
}
System.out.println("Hello World!");
}
}上面的程序的try块后增加了finally块,用于回收在try块中打开的物理资源。程序的catch块中①处有一条return语句,该语句强制方法返回。通常情况下,一旦方法里执行到return语句的地方,程序将立即结束该方法,但这里不会,虽然return也强制方法立即结束,但一定会先执行finally块里的代码,运行上面的程序,看到的结果如下:a.txt(系统找不到指定的文件。)
程序已经执行了finally里的资源回收!
上面运行结果表明方法返回之前还是执行了finally块的代码。将①处的return语句注释掉,取消②处代码的注释,即在异常处理的catch块中使用System.exit(1)来退出虚拟机,执行上面代码,看到如下结果:a.txt(系统找不到指定的文件。)
上面执行结果表明finally块没有被执行。如果在异常处理代码中使用System.exit(1)语句来退出虚拟机,则finally块将失去执行的机会。除非在try块、catch块中调用了退出虚拟机的方法,否则不管在try块、catch块中执行怎样的代码块,出现怎样的情况,异常处理的finally块总会被执行。通常情况下,不要在finally块中使用如return或throw等导致方法终止的语句,一旦在finally块中使用了return或throw语句,将会导致try块、catch块中的return、throw语句失效。看下面程序:public class TestFinallyFlow
{
public static void main(String[] args) throws Exception
{
boolean a=test();
System.out.println(a);
}
public static boolean test()
{
· try
{
//因为finally块中包含了return语句,则下面的return语句失去作用
return true;
}
finally
{
return false;
}
}
}
运行上面程序,将打印出false的结果。上面程序在finally块中定义了一个return false语句,这将导致try块中的return true失去作用。
当Java程序执行try、catch块是遇到了return语句或throw语句,这两个语句都会导致该方法立即结束,所以系统并不会立即执行这两个语句,而是去寻找该异常处理流程中是否包含finally块,如果没有finally块,程序立即执行return语句或throw语句,方法终止。如果有finally块,系统立即开始执行finally块----只有当finally块执行完成之后,系统才会再次跳回来执行try块、catch块里的return语句或throw语句。如果finally块里使用了return或throw等导致方法终止的语句,则finally块已经终止了方法,系统不会跳回去执行try块、catch块里的任何代码。