系列目录
文章目录
前言
本文介绍java中finally的用法相关基础内容。
提示:以下是本篇文章正文内容,下面案例可供参考
一、finally的使用场景
当方法获得了一些本地资源,且在退出之前必须被回收,比如:开启的文件,数据库连接,网络连接等,正常情况下,不管是否捕获异常finally块都会执行
二、finally中的语句是否一定会执行
1.如何实现finally总被执行
采用拷贝 finally 语句块的方式来实现 finally 总会执行的语义逻辑
代码如下(示例):
public class Test {
public static void main(String[] args) {
try {
System.out.println("try");;
} catch (Exception e) {
System.out.println("catch");
} finally {
System.out.println("finally");
}
}
}

将finally中的代码块复制到try以及catch代码块中
2.finally任何情况下都会执行吗
不是的,以下情况finally不会执行
-
jvm停止运行
比如调用system.exit()或者Runtime.getRuntime().halt(); -
执行try或catch代码的线程被中断或杀死
比如守护线程刚开始执行到 finally 代码块,此时没有任何其他非守护线程,那么虚拟机将退出,此时 JVM 不会等待守护线程的 finally 代码块执行完成 -
try代码块中无限循环或者执行不到try代码块
三、finally的执行顺序
1.当遇到return,continue,break这三个可以打乱代码顺序执行语句的关键词
finally语句块是在return执行后,返回前执行的,在循环被跳过(continue)和中断(break)之前被执行的。
测试return代码如下(示例):
public class ReturnTest {
// 测试return语句
public ReturnClass testReturn() {
try {
return new ReturnClass();
} catch (Exception e) {
e.printStackTrace();
} finally {
System.out.println("执行了finally语句");
}
return null;
}
public static void main(String[] args) {
ReturnTest rt = new ReturnTest();
// 测试return语句
rt.testReturn();
System.out.println();
}
}
class ReturnClass {
public ReturnClass() {
System.out.println("执行了return语句");
}
}
//执行结果
执行了return语句
执行了finally语句
测试continue代码如下(示例):
public class ContinueTest {
// 测试continue语句
public void testContinue() {
for (int i = 0; i < 3; i++) {
try {
if (i == 0) {
continue;
}
System.out.println(i);
} catch (Exception e) {
e.printStackTrace();
} finally {
System.out.println("执行了finally语句");
}
}
}
public static void main(String[] args) {
ContinueTest ct = new ContinueTest();
// 测试continue语句
ct.testContinue();
System.out.println();
}
}
//执行结果
执行了finally语句
1
执行了finally语句
2
执行了finally语句
continue测试代码的字节码如下:
0 iconst_0
1 istore_1
2 iload_1
3 iconst_3
4 if_icmpge 74 (+70)
7 getstatic #2 <java/lang/System.out : Ljava/io/PrintStream;>
10 iload_1
11 invokevirtual #3 <java/io/PrintStream.println : (I)V>
14 iload_1
15 iconst_1
16 if_icmpne 30 (+14) //跳转到finally
19 getstatic #2 <java/lang/System.out : Ljava/io/PrintStream;>
22 ldc #4 <执行了finally语句>
24 invokevirtual #5 <java/io/PrintStream.println : (Ljava/lang/String;)V>
27 goto 68 (+41)
30 getstatic #2 <java/lang/System.out : Ljava/io/PrintStream;>
33 ldc #4 <执行了finally语句>
35 invokevirtual #5 <java/io/PrintStream.println : (Ljava/lang/String;)V>
38 goto 68 (+30)
41 astore_2
42 aload_2
43 invokevirtual #7 <java/lang/Exception.printStackTrace : ()V>
46 getstatic #2 <java/lang/System.out : Ljava/io/PrintStream;>
49 ldc #4 <执行了finally语句>
51 invokevirtual #5 <java/io/PrintStream.println : (Ljava/lang/String;)V>
54 goto 68 (+14)
57 astore_3
58 getstatic #2 <java/lang/System.out : Ljava/io/PrintStream;>
61 ldc #4 <执行了finally语句>
63 invokevirtual #5 <java/io/PrintStream.println : (Ljava/lang/String;)V>
66 aload_3
67 athrow
68 iinc 1 by 1
71 goto 2 (-69)
74 return
测试break代码如下(示例):
public class BreakTest {
// 测试break语句
public void testBreak() {
for (int i = 0; i < 3; i++) {
try {
System.out.println(i);
if (i == 1) {
break;
}
} catch (Exception e) {
e.printStackTrace();
} finally {
System.out.println("执行了finally语句");
}
}
}
public static void main(String[] args) {
BreakTest bt = new BreakTest();
// 测试break语句
bt.testBreak();
}
}
//执行结果
0
执行了finally语句
1
执行了finally语句
2.在finally中修改返回值对返回值的影响
返回值为基本数据类型——不会影响返回的值,但是变量的值会发生改变;返回值为引用变量类型——会影响返回值。

3.finally中有return
会覆盖try/catch中的返回值

本文详细探讨了Java中finally关键字的使用场景,包括确保资源释放、finally语句的执行条件以及在return、continue、break等情况下finally的执行顺序。特别指出,即使在特定条件下finally也可能不执行,例如系统退出或线程中断。同时,文章还讨论了finally中return语句对返回值的影响。
296





