前言:又是被“长得像”支配的一天

坐标:寝室(舍友在开黑,我在跟 JVM 搏斗)

状态:刚喝完一罐红牛,脑子有点飘。

碎碎念: 兄弟们,今天下午在图书馆刷面试题,看到一个题目:“请简述 final, finally, finalize 的区别”。 我当时心里想:这不就是“张三、张三丰、张三疯”的区别吗? 结果一查资料,好家伙,这三个东西除了名字前五个字母一样,剩下的完全不是一回事儿。一个是“封印”,一个是“收尾”,还有一个是“遗言”。

为了不让大家在面试官面前露出那种“清澈且愚蠢”的眼神,我连夜整理了这份深度笔记。看完这一篇,这三兄弟你绝对能拿捏得死死的!

🚀 目录

  1. final:不仅是“封印”,更是“绝后”

    • 1.1 修饰变量:说不改就不改

    • 1.2 修饰方法:不许你“反叛”

    • 1.3 修饰类:断子绝孙修饰符

  2. finally:哪怕天塌下来,我也得执行

    • 2.1 铁杆收尾人:try-catch 的黄金搭档

    • 2.2 唯一能让我“下班”的情况

    • 2.3 避坑:千万别在 finally 里写 return!

  3. finalize:那个不靠谱的“遗言”

    • 3.1 对象临终前的最后挣扎

    • 3.2 为什么 Java 官方都想把它埋了?

  4. 核心对比:一张表教你做人

  5. 面试天坑:这几个题你能做对吗?

  6. 结语

1. final:不仅是“封印”,更是“绝后”

final 的核心思想就是:“到此为止,不许变了”。

1.1 修饰变量(常量)

  • 基本类型:值不能变。你给它 10,它这辈子就是 10。

  • 引用类型地址不能变,但对象的内容可以变!

    • 大学生比喻:就像你找了个女朋友(final),你不能换人(地址不能改),但你女朋友今天穿裙子还是明天穿牛仔裤(属性改动),你管不着。

1.2 修饰方法:不许你“反叛”

当一个方法被 final 修饰时,子类可以继承它,但**不能重写(Override)**它。

  • 场景:就像老爸传给你一套祖传绝技,你可以学,但你不能私自改招式。

1.3 修饰类:断子绝孙修饰符

final 修饰的类不能被继承

  • 经典案例String 类。为什么要给 Stringfinal?为了安全!如果谁都能继承 String 然后乱改里面的逻辑,那 Java 整个世界都乱套了。

2. finally:哪怕天塌下来,我也得执行

finally 是异常处理机制 try-catch-finally 的最后一部分。

2.1 铁杆收尾人

它的唯一使命就是:清理现场。 不管是 try 块里的代码顺利跑完,还是中途出 Bug 进了 catchfinally 里的代码百分之百会执行

  • 用途:关闭 IO 流、断开数据库连接、释放锁。

2.2 唯一能让我“下班”的情况

只有一种情况 finally 不执行:你在执行它之前,强行把虚拟机给关了——System.exit(0)

2.3 避坑:千万别在 finally 里写 return!

这是一个非常阴险的面试题。 如果在 tryreturn 1,在 finallyreturn 2,结果是多少? 答案是 2! 因为 finally 会覆盖掉之前的返回值。这种写法会被同事打死的,千万别试。

3. finalize:那个不靠谱的“遗言”

finalizeObject 类里的一个方法。

3.1 对象临终前的最后挣扎

当垃圾回收器(GC)觉得一个对象没用了,准备收走它时,会先调用它的 finalize() 方法。

  • 大学生比喻:就像一个人被拉去执行死刑前,法官问你:“还有啥遗言没?”

3.2 为什么 Java 官方都想把它埋了?

  1. 不确定性:你不知道 GC 啥时候来,所以你不知道 finalize 啥时候执行,甚至可能永远不执行。

  2. 性能差:有了它,GC 的负担会重很多。

  3. 已过时:Java 9 之后已经明确标注为 @Deprecated(不推荐使用)。 结论:除了面试,平时写代码千万别碰它

4. 核心对比:一张表教你做人

特征

含义

角色

常用场景

final

最终的

修饰符(类、方法、变量)

定义常量、防止重载/继承

finally

最终执行

语句块(异常处理)

资源回收(关流、关连接)

finalize

终结处理

方法(Object 类方法)

垃圾回收前的遗愿(已废弃)

5. 面试天坑:这几个题你能做对吗?

Q1:final 修饰的 List,能执行 add 操作吗?

答案:能。 解析:因为 final 修饰引用类型时,限制的是地址。add 操作改变的是 List 内部的内容,地址没变。

Q2:如果 try 块里有 return,finally 还会执行吗?

答案:会,而且是在 return 指令执行之前执行。 解析:JVM 会先保存好返回值,然后去跑 finally,跑完了再把刚才保存的值返回回去。

6. 结语

呼……写完这一篇,感觉整个人都“final”了。 这三兄弟虽然名字像,但其实分工明确:

  • 想让东西不变?找 final

  • 想最后打扫卫生?找 finally

  • 至于 finalize?让它随风而去吧,咱们这辈子最好别再见了。

作为大学生的我们,学 Java 不仅是学语法,更是学一种规则。 希望这篇文章能帮你搞定面试官,早日拿到心仪的 Offer!

如果你觉得写得还算走心,点个赞支持一下!下期咱们聊聊String为什么不可变

更多推荐