一、finally执行一些资源关闭
class Wolf implements Serializable
{
private String name;
public Wolf(String name)
{
System.out.println("调用有参数的构造器");
this.name = name;
}
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj.getClass() == Wolf.class) {
Wolf target = (Wolf)obj;
return target.name.equals(this.name);
}
return false;
}
public int hashCode() {
return name.hashCode();
}
}
public class TrackFinally {
/**
* @param args
*/
public static void main(String[] args) throws Exception {
Wolf w = new Wolf("灰太狼");
System.out.println("Wolf对象创建完成");
Wolf w2 = null;
ObjectOutputStream oos = null;
ObjectInputStream ois = null;
try {
//创建对象输出流
oos = new ObjectOutputStream(new FileOutputStream("a.bin"));
//创建对象输入流
ois = new ObjectInputStream(new FileInputStream("a.bin"));
//序列化输出Java对象
oos.writeObject(w);
oos.flush();
//反序列化恢复Java对象
w2 = (Wolf)ois.readObject();
} finally {
//使用finally来回收资源
oos.close();
ois.close();
}
}
}
上述程序使用finally快来保证程序资源被关闭,但是这样也可能不安全,程序刚开始时指定oos = null; ois = null;完全有可能在程序运行过程中初始化oos之前就发生了异常,那么oos,ois还没来得及初始化,因此oos、ois根本无需关闭,可以更改finally块代码为
finally {
//使用finally来回收资源
if (oos != null) {
oos.close();
}
if (ois != null) {
ois.close();
}
}
二、finally块当遇到System.exit(0)时,不会执行
public class ExitFinally {
/**
* @param args
*/
public static void main(String[] args) throws Exception {
FileOutputStream fos = null;
try {
fos = new FileOutputStream("a.bin");
System.out.println("程序打开物理资源!");
System.exit(0);
} finally {
//使用finally来关闭资源
if (fos != null) {
try {
fos.close();
} catch (Exception ex) {
ex.printStackTrace();
}
}
System.out.println("程序关闭了物理资源!");
}
}
}
程序结果:
不论try块是正常结束,还是中途非正常退出,finally块的确都会执行,然而这个程序中,try块根本没有结束其执行过程,System.exit(0);将停止当前线程和所有其他当场死亡的线程,finally块并不能让已经停止的线程继续执行!
三、finally遇到return
public class FinallyFlowTest {
/**
* @param args
*/
public static void main(String[] args) {
int a = test();
System.out.println(a);
}
public static int test() {
int count = 5;
try {
//因为finally块中包含了return语句
//则下面的return语句不会立即返回
return ++count;
//throws new RuntimeException("测试异常");
} finally {
System.out.println("finally块被执行!");
return count++;
}
}
}
上面程序的try块中是return ++count,而finally块中是return count++;程序结果:
这说明finally块执行,return count++被执行了,但是返回值为6,说明return ++count;没有被执行,程序在finally块中直接返回了,没有退回到try块中再执行return ++count;
当Java程序执行try块,catch块时遇到了return语句,return语句会导致该方法立即结束。系统执行完return语句之后,并不会立即结束该方法,而是去寻找异常处理流程中是否包含finally块,如果没有finally块,方法终止,返回相应的返回值,如果有finally块,系统执行finally块,finally块执行完,系统跳回根据return结束方法,如果finally块中有return结束方法,则直接在finally块结束方法,系统不会跳回try块、catch块执行。对于try块中直接throw异常处理流程一样