Java的finally块执行分析

本文探讨了Java中finally块的执行机制,包括资源关闭的最佳实践、遇到System.exit(0)时的行为以及与return语句交互的情况。通过具体示例,深入解析了finally块如何确保资源释放并影响方法返回值。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、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异常处理流程一样

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值