首页 > 编程语言 >[Java基础]Finally

[Java基础]Finally

时间:2024-07-26 20:39:41浏览次数:14  
标签:Java 钩子 代码 基础 finally System try Finally 执行

finally中的代码一定会执行吗?

通常在面试中,只要是疑问句一般答案都是“否定”的,因为如果是“确定”和“正常”的,那面试官就没有必要再问了嘛,而今天这道题的答案也是符合这个套路。

1.典型回答
正常运行的情况下,finally 中的代码是一定会执行的,但是,如果遇到以下异常情况,那么 finally 中的代码就不会继续执行了:

程序在 try 块中遇到 System.exit() 方法,会立即终止程序的执行,这时 finally 块中的代码不会被执行,例如以下代码:
public class FinallyExample {
public static void main(String[] args) {
try {
System.out.println("执行 try 代码.");
System.exit(0);
} finally {
System.out.println("执行 finally 代码.");
}
}
}
以上程序的执行结果如下:

在 try 快中遇到 Runtime.getRuntime().halt() 代码,强制终止正在运行的 JVM。与 System.exit()方法不同,此方法不会触发 JVM 关闭序列。因此,当我们调用 halt 方法时,都不会执行关闭钩子或终结器。实现代码如下:
public class FinallyExample {
public static void main(String[] args) {
try {
System.out.println("执行 try 代码.");
Runtime.getRuntime().halt(0);
} finally {
System.out.println("执行 finally 代码.");
}
}
}
以上程序的执行结果如下:

程序在 try 块中遇到无限循环或者发生死锁等情况时,程序可能无法正常跳出 try 块,此时 finally 块中的代码也不会被执行。
掉电问题,程序还没有执行到 finally 就掉电了(停电了),那 finally 中的代码自然也不会执行。
JVM 异常崩溃问题导致程序不能继续执行,那么 finally 的代码也不会执行。
钩子方法解释
在编程中,钩子方法(Hook Method)是一种由父类提供的空或默认实现的方法,子类可以选择性地重写或扩展该方法,以实现特定的行为或定制化逻辑。钩子方法可以在父类中被调用,以提供一种可插拔的方式来影响父类的行为。
钩子方法通常用于框架或模板方法设计模式中。框架提供一个骨架或模板,其中包含一些已经实现的方法及预留的钩子方法。具体的子类可以通过重写钩子方法来插入定制逻辑,从而影响父类方法的实现方式。

2.考点分析
正常运行的情况下,finally 中的代码是一定会执行的,但是,如果遇到 System.exit() 方法或 Runtime.getRuntime().halt() 方法,或者是 try 中发生了死循环、死锁,遇到了掉电、JVM 崩溃等问题,那么 finally 中的代码也是不会执行的。

3.知识扩展
System.exit() 和 Runtime.getRuntime().halt() 都可以用于终止 Java 程序的执行,但它们之间有以下区别:

System.exit():来自 Java.lang.System 类的一个静态方法,它接受一个整数参数作为退出状态码,通常非零值表示异常终止,使用零值表示正常终止。其中,最重要的是使用 exit() 方法,会执行 JVM 关闭钩子或终结器。
Runtime.getRuntime().halt():来自 Runtime 类的一个实例方法,它接受一个整数参数作为退出状态码。其中退出状态码只是表示程序终止的原因,很少在程序终止时使用非零值。而使用 halt() 方法,不会执行 JVM 关闭钩子或终结器。
例如以下代码,使用 exit() 方法会执行 JVM 关闭钩子:

class ExitDemo {
// 注册退出钩子程序
static {
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
System.out.println("执行 ShutdownHook 方法");
}));
}
public static void main(String[] args) {
try {
System.out.println("执行 try 代码。");
// 使用 System.exit() 退出程序
System.exit(0);
} finally {
System.out.println("执行 finally 代码。");
}
}
}
以上程序的执行结果如下:

而 halt() 退出的方法,并不会执行 JVM 关闭钩子,示例代码如下:

class ExitDemo {

// 注册退出钩子程序
static {
    Runtime.getRuntime().addShutdownHook(new Thread(() -> {
        System.out.println("执行 ShutdownHook 方法");
    }));
}

public static void main(String[] args) {
    try {
        System.out.println("执行 try 代码。");
        // 使用 Runtime.getRuntime().halt() 退出程序
        Runtime.getRuntime().halt(0);
    } finally {
        System.out.println("执行 finally 代码。");
    }
}

}
以上程序的执行结果如下:

小结
正常运行的情况下,finally 中的代码是一定会执行的,但是,如果遇到 System.exit() 方法或 Runtime.getRuntime().halt() 方法,或者是 try 中发生了死循环、死锁,遇到了掉电、JVM 崩溃等问题,finally 中的代码是不会执行的。而 exit() 方法会执行 JVM 关闭钩子方法或终结器,但 halt() 方法并不会执行钩子方法或终结器。

标签:Java,钩子,代码,基础,finally,System,try,Finally,执行
From: https://www.cnblogs.com/DCFV/p/18326215

相关文章

  • JAVA集中学习第二周学习记录(四)
    系列文章目录第一章JAVA集中学习第一周学习记录(一)第二章JAVA集中学习第一周项目实践第三章JAVA集中学习第一周学习记录(二)第四章JAVA集中学习第一周课后习题第五章JAVA集中学习第二周学习记录(一)第六章JAVA集中学习第二周项目实践第七章JAVA集中学习第二......
  • [Java面向对象]final
    final简介[2]final关键字可用于多个场景,且在不同场景具有不同的作用。首先,final是一个非访问修饰符,仅适用于变量,方法或类。下面是使用final的不同场景:java中的final关键字上面这张图可以概括成:当final修饰变量时,被修饰的变量必须被初始化(赋值),且后续不能修改其值,实质上是常......
  • 【Kubernetes】初识K8S基础
    目录一.K8S概述1.K8S背景物理机的缺点虚拟机特点(解决了物理机的缺点)虚拟机缺点容器化特点(解决了虚拟机的缺点)容器化缺点2.K8S基本概念2.1.作用2.2.特点二.K8S 集群架构与组件1.集群架构介绍2.核心组件2.1.Master组件Kube-apiserver:是所有服务请求的统一访问入......
  • JAVA集中学习第二周项目实践[图书管理系统]
    系列文章目录第一章JAVA集中学习第一周学习记录(一)第二章JAVA集中学习第一周项目实践第三章JAVA集中学习第一周学习记录(二)第四章JAVA集中学习第一周课后习题第五章JAVA集中学习第二周学习记录(一)第六章JAVA集中学习第二周项目实践文章目录系列文章目录......
  • 音视频入门基础:WAV专题(2)——WAV格式简介
    注:本文有部分内容引用了维基百科:https://zh.wikipedia.org/wiki/WAV一、引言WaveformAudioFileFormat(缩写WAVE或WAV)是微软与IBM公司所开发在个人电脑存储音频流的编码格式,在Windows平台的应用软件受到广泛的支持。此格式属于资源交换文件格式(RIFF)的应用之一(关于RIFF格......
  • [Java并发]
    多线程的价值(这里展示的是网上的答案,我觉得真正重要的是减少进程切换的代价)发挥多核CPU的优势多线程,可以真正发挥出多核CPU的优势来,达到充分利用CPU的目的,采用多线程的方式去同时完成几件事而不互相干扰。防止阻塞从程序运行效率的角度来看,单核CPU不但不会发挥出多线程的......
  • java位运算
    位运算符:针对二进制的值补码形式进行计算的&|^(相同为0,不同为1)~<<>>>>>publicclassWeiOptDemo1{publicstaticvoidmain(String[]args){bytea1=3;byteb1=4;System.out.println(a1&b1);System.out.println(a1|b1);System.o......
  • 基础数论 欧拉定理与exgcd
    欧拉定理:若正整数\(a,n\)互质,则\(a^{\varphi(p)}\equiv1(\bmodp)\)推论(扩展欧拉定理):\[a^b\equiv\begin{cases}a^{b\\bmod\\varphi(p)}\\\\\\\\\\gcd(a,p)=1\\a^b\\\\\\\\\\\\\\\\\\\\\\gcd(a,p)!......
  • 基础数论 质数与约数
    基础数论前置芝士:等比数列求和:\(S_n=a_0\frac{1-q^n}{1-q}\)质数与约数:整除与约数设\(n\)为非负整数,\(d\)为正整数,若\(\frac{n}{d}\)为整数,则称\(d\)整除\(n\),记为\(d\midn\)。此时,则称\(d\)是\(n\)的约数,或因数、因子;称\(n\)为\(d\)的倍数。质数......
  • 基础数论 整除分块与欧拉函数
    整除分块:例题:已知\(f(n)=\sum\limits_{i=1}^{n}\left\lfloor\frac{n}{i}\right\rfloor\),给定\(n\),求\(f(n)\)的值。固然可以\(O(n)\)暴力,但显然会\(TLE\)。计算一下前几项的值之后可以发现\(\left\lfloor\frac{n}{i}\right\rfloor\)的取值在连续的一段区间内是......