题目重点:逐项说明 final 变量/方法/类、finally 执行时机及资源管理,避免把 final 引用当不可变对象。
题意与假设
这道练习题保留了面经中值得训练的核心约束,并将需要澄清的条件单独列出。现场拿到变体时,先和面试官确认这些条件。
- 按 Java 语言常见语义回答,具体编译器/版本和 try-with-resources 细节以所用 JDK 为准。
解题路线
- `final` 变量只能赋值一次;若是引用变量,引用不能指向新对象,但被引用对象仍可能可变。`final` 方法不能被子类覆盖,`final` 类不能继承。
- `finally` 是 try/catch 后的清理块,通常无论正常返回还是抛异常都会执行;但进程被强制终止、JVM 崩溃等情形不能保证。`finally` 自己返回或抛异常会覆盖原返回/异常,故避免在其中写 return。
- 资源关闭优先 try-with-resources,自动处理逆序 close 和 suppressed exception;`finally` 适合释放非 AutoCloseable 状态或保证锁释放。
- `finalize` 是旧式对象终结钩子,执行时机不可靠、已废弃,不应用于确定性资源释放;这不是题目明示问题,只用于区分近似词。
手动走一遍
`final List<String> xs = new ArrayList<>(); xs.add("a")` 合法,但 `xs = new ArrayList<>()` 不合法。try 中 return 1、finally 中仅清理时返回 1;若 finally 再 return 2,最终变 2。
规模与取舍
语言语义题无统一算法复杂度;try-with-resources 关闭每个资源的成本取决于 close 实现。性能讨论不应替代正确的生命周期语义。
易错点与追问
容易失分的边界
- 把 final 引用误认为对象不可变。
- 说 finally 在任何机器故障下都必执行。
- 在 finally 中 return 覆盖异常。
- 用 finalize 释放文件/锁。
- 把方法 final 与 static 混同。
继续深挖
- final field 的安全发布与线程安全是同一回事吗?
- try-with-resources 多个 close 都失败时怎样保留异常?
- final class 还能实现接口吗?
- finally 与 catch 的执行顺序?
