为了保持我一贯简单粗暴的风格,先上结论吧
情况1:try{return1} catch{} finally{} return2;
程序在执行return1之前会先执行finally,然后返回try中执行return1。由于try中已经有return,所以return2不再执行。
情况2:try{} catch{return1} finally{} return2;同情况1。
情况3:try{return1} catch{} finally{return2} ;
程序执行try中return之前(包括return语句中的表达式运算)进入finally中执行,执行return2后退出。
情况4:try{} catch{return1} finally{return2} ;同情况3
总结:try语句在返回前会将其所有的操作执行完,保留好要返回的值,而后转入finally中执行,而后分为以下三种情况:
1、如果finally中有return语句,则会将try中的return语句“覆盖”掉,直接执行finally中的return语句,得到返回值,这样便无法得到try之前保留好的返回值。例如情况3,4
2、如果finally中没有return语句,也没有改变要返回值,则执行完finally中的语句后,会接着执行try中的return语句,返回之前保留的值。例如情况1,2
另外要注意:
如果finally中没有return语句,但是改变了要返回的值,这里有点类似与引用传递和值传递的区别,分以下两种情况:
- 1)如果return的数据是基本数据类型或文本字符串,则在finally中对该基本数据的改变不起作用,try中的return语句依然会返回进入finally块之前保留的值。
- 2)如果return的数据是引用数据类型,而在finally中对该引用数据类型的属性值的改变起作用,try中的return语句返回的就是在finally中改变后的该属性的值。
具体示例可查看 https://itimetraveler.github.io/2017/09/20/%E3%80%90Java%E3%80%91try-catch-finally%E8%AF%AD%E5%8F%A5%E4%B8%ADreturn%E7%9A%84%E6%89%A7%E8%A1%8C%E9%A1%BA%E5%BA%8F%E6%80%9D%E8%80%83/#%E6%80%BB%E7%BB%93