Java基础:理解try...catch...finally的使用
try...catch...finally基本大家都会用,也很少出问题,但当 try 语句块里增加存在return或System.exit()时会怎么处理,可能就有些疑惑和不确定了,下面来演示下这两种情况。
try 里面有return
当try...catch...finally中有return时,通常会先算出返回值并保存,再执行 finally,最后再完成返回(可通过字节码了解顺序)。对基本类型等已保存的返回值,finally 里再改原局部变量,一般不会改变这次返回结果——但不要绝对化,见下文补充。
一道面试题:在try时里有个return语句,程序会怎么走,返回值是多少?
1 | public class TryCatchFinally { |
返回的结果是:AB2,为什么不是ABC3?
打断点分析,finally执行完后,不是继续往下走,而是带着 try 里已保存的返回值返回,程序结束。
- 编译后的大致处理:
当try语句中有return语句时,编译会作如下处理:- 将 return 的返回值保存到局部变量。(对基本类型/不可变返回值:finally 再改原变量,通常不影响已保存的返回值。)
- 执行
jsr指令执行finally。 - finally执行完后,返回return语句前面已经保存到局部变量的值,程序结束(前提是 finally 没有再 return)。
- finally后面语句不会执行。
- 示例代码解释
return ++x,x = 2 , 把值保存到局部变量中;finally ++x执行完后,x = 3;- 返回到
return语句保存到局部变量里的值,即返回的是值是2。
- 补充(弱化绝对化说法):
- 若 finally 中再次 return,会覆盖 try/catch 中已准备好的返回值。
- 若返回的是对象引用,finally 里修改该对象的字段,调用方能看到字段变化(返回的仍是同一引用)。
finally 里面有 return
- try和catch里面的return会被 finally 截断。
- 进入finally 执行到 return则按 finally 的返回值结束方法。
不会再跳回到try和catch里面的return执行。
使用建议
- finally 中最好不要有 return ,也没必要。
- 不要在 finally 中抛出异常, 不要在 finally 中做业务处理,finally 通常用于资源释放。
- 尽量不要在
try...catch...finally中使用 return,return 语句写在方法最后面。
如果有,程序会提前结束,try...catch的 return 会跳过,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/

