Java基础:理解try...catch...finally的使用

try...catch...finally基本大家都会用,也很少出问题,但当 try 语句块里增加存在returnSystem.exit()时会怎么处理,可能就有些疑惑和不确定了,下面来演示下这两种情况。

try 里面有return

try...catch...finally中有return时,通常会先算出返回值并保存,再执行 finally,最后再完成返回(可通过字节码了解顺序)。对基本类型等已保存的返回值,finally 里再改原局部变量,一般不会改变这次返回结果——但不要绝对化,见下文补充。

一道面试题:在try时里有个return语句,程序会怎么走,返回值是多少?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
public class TryCatchFinally {

public static void main(String[] args) {
System.out.println(tryCatchTest()); // #1
}

public static int tryCatchTest() {
int x = 1; // #2

try {
System.out.print("A"); // #3
return ++x; // #4,x=2 保存到局部变量 ;#7直接返回局部变量,不会再加

} catch (Exception e) {
// 无异常,不执行
System.out.print("D");

} finally {
System.out.print("B"); // #5
++x; // #6
}
System.out.print("C");
return x;
}
}

返回的结果是:AB2,为什么不是ABC3? 
打断点分析,finally执行完后,不是继续往下走,而是带着 try 里已保存的返回值返回,程序结束。

  • 编译后的大致处理:
    try语句中有return语句时,编译会作如下处理:
    1. return 的返回值保存到局部变量。(对基本类型/不可变返回值:finally 再改原变量,通常不影响已保存的返回值。)
    2. 执行jsr指令执行finally
    3. finally执行完后,返回return语句前面已经保存到局部变量的值,程序结束(前提是 finally 没有再 return)。
    4. finally后面语句不会执行。
  • 示例代码解释
    1. return ++x,x = 2 , 把值保存到局部变量中;
    2. finally ++x执行完后,x = 3;
    3. 返回到return语句保存到局部变量里的值,即返回的是值是2
  • 补充(弱化绝对化说法):
    1. finally 中再次 return,会覆盖 try/catch 中已准备好的返回值。
    2. 若返回的是对象引用,finally 里修改该对象的字段,调用方能看到字段变化(返回的仍是同一引用)。

finally 里面有 return

  1. trycatch里面的return会被 finally 截断。
  2. 进入finally 执行到 return则按 finally 的返回值结束方法。
    不会再跳回到trycatch里面的return执行。

使用建议

  1. finally 中最好不要有 return ,也没必要。
  2. 不要在 finally 中抛出异常, 不要在 finally 中做业务处理,finally 通常用于资源释放。
  3. 尽量不要在try...catch...finally中使用 return,return 语句写在方法最后面。
    如果有,程序会提前结束,try...catchreturn 会跳过,finally 后面的语句也不会执行。编译器会把finally中的return标识为warning

System.exit(0)

只要执行到System.exit(0)语句,就程序结束,不管是在try...catch...finally哪个位置。

Java基础:理解try...catch...finally的使用

http://blog.gxitsky.com/2018/03/25/Java-jdk-5-try-catch-finally/

作者

光星

发布于

2018-03-25

更新于

2026-08-16

许可协议

评论