finally中赋值是否影响返回值取决于类型:基本类型因暂存值副本而不影响,引用类型因暂存地址副本且可修改对象状态而影响;string因不可变故修改引用指向无效。

在异常处理中,finally块里的赋值操作是否影响返回值,关键取决于方法返回的是基本类型还是引用类型——不是“能不能改”,而是“改的是谁”。
finally 中的修改对返回值是否生效?
Java 规定:无论 try 或 catch 中是否有 return,只要程序正常执行到 finally(未被 System.exit 或断电中断),就一定会执行 finally 块。但return 的值是在进入 finally 之前就确定并暂存的,后续修改能否体现,取决于这个“暂存值”的性质:
- 基本类型:暂存的是值的副本 → finally 中改 a = 28,不影响已暂存的 18
- 引用类型:暂存的是对象地址的副本 → finally 中通过该地址修改对象内部字段(如 p.age = 28),返回时取的仍是这个地址,而地址指向的对象已被更新
典型对比代码说明
以下两个方法返回结果不同,根源就在数据类型的本质差异:
- 引用类型示例:返回 Person 对象,finally 修改其 age 字段 → 调用方拿到的是 age = 28 的对象
- 基本类型示例:返回 int 值,finally 修改局部变量 a → 不影响已决定返回的原始值 18
为什么 String 是引用类型,但类似操作却不生效?
String 虽是引用类型,但它是不可变(immutable)的。例如:
- 在 finally 中写
s = "new",只是让局部变量 s 指向新字符串,原返回值仍指向旧字符串 - 这和
p.age = 28有本质区别:后者是通过地址修改堆中对象状态;前者是改变栈中引用的指向 - 真正体现“引用类型可被修改”的,是可变对象,如 ArrayList、自定义类、StringBuilder 等
实际开发中的注意点
这种行为容易引发隐蔽 bug,尤其在封装工具方法时:
- 避免在 finally 中修改参与 return 的局部变量(尤其是基本类型),逻辑易误解
- 若需统一后置处理,优先用明确的变量赋值 + 单一 return,而非依赖 finally 的副作用
- 对引用类型,要清楚你修改的是“对象状态”还是“引用指向”——只有前者会影响已准备返回的对象











