Finally使用时注意事项

本文详细解析finally语句的使用场景、执行机制,包括无异常、有异常无处理器、有异常有处理器的情况,以及finally在System.exit()、halt函数和守护线程中的特殊行为。特别关注finally在try循环和程序退出时的执行规律。
摘要由CSDN通过智能技术生成

finally的使用

通常情况下finally代码块会定义在try语句和catch语句之后,在方法结束前执行,且无论有没有异常finally语句都会执行。

1.finally示例

private void finalllyTest() {
	try {
		System.out.println("try代码块执行了");
		throw new Exception();
	} catch (Exception e) {
		System.out.println("catch代码块执行了");
	} finally {
		System.out.println("finally代码块执行了");
	}
}
try代码块执行了
catch代码块执行了
finally代码块执行了

2.删除catch的finally语句

private void finalllyTest() {
	try {
		System.out.println("try代码块执行了");
	} finally {
		System.out.println("finally代码块执行了");
	}
}
try代码块执行了
finally代码块执行了

有无catch与finally的的执行无关

3.finally的使用场景

finally代码块多数情况下都会执行,一般在其中执行一些数据库关闭、文件流关闭、释放线程等操作。

4.finally的执行机制

没有异常
	try {
        System.out.println("try执行了");
    } finally {
        System.out.println("finally执行了");
    }
try执行了
finally执行了
有异常无处理器
try {
	System.out.println("try执行了");
	throw new Exception();
} finally {
	System.out.println("finally执行了");
}

在这里插入图片描述
有异常无异常处理器的代码块会报错

有异常处理器
 private void finallyTest() {
        try {
            System.out.println("try执行了");
            try {
                throw new Exception();
            } catch (Exception e) {
                e.printStackTrace();
            }
        } finally {
            System.out.println("finally执行了");
        }
    }

在这里插入图片描述

try代码块有返回值
/**
 * @author 张阔
 */
public class Test {
    public static void main(String[] args) {
        Test t = new Test();
        t.finallyTest();

    }
    private Object finallyTest() {
        try {
            System.out.println("try执行了");
            return "nothing";
        } catch (Exception e) {
            System.out.println("catch执行了");
        } finally {
            System.out.println("finally执行了");
        }
        return "everything";
    }

}

在这里插入图片描述
try语句中有返回值不影响finally正常执行

catch中有返回值
/**
 * @author 张阔
 */
public class Test {
    public static void main(String[] args) {
        Test t = new Test();
        t.finallyTest();

    }
    private Object finallyTest() {
        try {
            System.out.println("try执行了");
            throw new Exception();
        } catch (Exception e) {
            System.out.println("catch执行了");
            return "nothing";
        } finally {
            System.out.println("finally执行了");
        }
    }
}

在这里插入图片描述
catch语句中有返回值不影响finally的正常运行

5.finally不执行的场景

虽然通常情况下finally都是执行的,但在个别情况下会跳过fianlly语句结束方法

调用System.exit()函数
/**
 * @author 张阔
 */
public class Test {
    public static void main(String[] args) {
        Test t = new Test();
        t.finallyTest(1);
        //t.finallyTest(0);

    }
    private void finallyTest(int n) {
        try {
            if (n == 1) {
                System.out.println("try执行了");
                throw new Exception();
            }
            System.exit(0);
        } catch (Exception e) {
            System.out.println("catch执行了");
            System.exit(0);
        } finally {
            System.out.println("finally执行了");
        }
    }
}

当n=1时
在这里插入图片描述
当n=0时
在这里插入图片描述
无论System.exit(0);语句在try代码块还是catch代码块中被执行,都越过finally结束了

注:
Sytstem.exit();
实际上调用了Runtime的方法,执行时可以等同于Runtime.getRuntime().exit();
用来终止当前运行的虚拟机

调用halt函数
/**
 * @author 张阔
 */
public class Test {
    public static void main(String[] args) {
        Test t = new Test();
    }
    private void finallyTest(int n) {
        try {
            System.out.println("try执行了");
            Runtime.getRuntime().halt(0);
            throw new Exception();
        } catch (Exception e) {
            System.out.println("catch执行了");
        } finally {
            System.out.println("finally执行了");
        }
    }
}

在这里插入图片描述
halt()方法与exit()作用相似,但有所不同,halt会强制停止当前运行的JAVA虚拟机,不会等待任何相关线程完成工作,此方法永远不能正常返回。

守护进程(暂时不理解=。=)
import java.util.concurrent.TimeUnit;
/**

 * Finally shoud be always run ?

 */
public class DaemonsDontRunFinally {

    public static void main(String[] args) {

        Thread t = new Thread(new ADaemon());

        t.setDaemon(true);

        t.start();

    }
}

class ADaemon implements Runnable {

    public void run() {

        try {

            System.out.println("start ADaemon...");

            TimeUnit.SECONDS.sleep(1);

        } catch (InterruptedException e) {

            System.out.println("Exiting via InterruptedException");

        } finally {

            System.out.println("This shoud be always run ?");

        }

    }

}

如果守护进程刚开始执行到finally代码块,此时没有任何其他非守护线程,那么虚拟机将退出,此时JVM不会等待守护线程的finally代码块执行完成。

try无限循环
/**
 * @author 张阔
 */
public class Test {
    public static void main(String[] args) {
        Test t = new Test();
        t.finallyTest();
    }
    private int finallyTest() {
        try {
            while (true) {
                
            }
        } catch (Exception e) {
            System.out.println("catch执行了");
        } finally {
            System.out.println("finally执行了");
        }
        return 10;
    }
}

finally:两眼一闭,这辈子运行不到我了。

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值