Java 核心技术面试精讲
杨晓峰
前 Oracle 首席工程师
125942 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 44 讲
Java 核心技术面试精讲
15
15
1.0x
00:00/00:00
登录|注册

第3讲 | 谈谈final、finally、 finalize有什么不同?

不推荐使用
对象在被垃圾收集前完成特定资源的回收
java.lang.Object的方法
try-finally、try-catch-finally
保证重点代码一定被执行
不可继承、不可修改、不可重写
修饰类、方法、变量
JDK自身使用的Cleaner机制的缺陷
替换finalize的机制
finalize的问题
final不是immutable
finalize的替代方法
finalize的问题
不推荐使用
特例情况
推荐使用Java 7中的try-with-resources语句
final的性能好处
final变量的不可变效果
修饰类、方法、变量
深入探讨的方面
面试官考察的知识点
finalize
finally
final
一课一练
知识扩展
对于finalize
对于finally
推荐使用final关键字
考点分析
典型回答
参考文章

该思维导图由 AI 生成,仅供参考

Java 语言有很多看起来很相似,但是用途却完全不同的语言要素,这些内容往往容易成为面试官考察你知识掌握程度的切入点。
今天,我要问你的是一个经典的 Java 基础题目,谈谈 final、finally、 finalize 有什么不同?

典型回答

final 可以用来修饰类、方法、变量,分别有不同的意义,final 修饰的 class 代表不可以继承扩展,final 的变量是不可以修改的,而 final 的方法也是不可以重写的(override)。
finally 则是 Java 保证重点代码一定要被执行的一种机制。我们可以使用 try-finally 或者 try-catch-finally 来进行类似关闭 JDBC 连接、保证 unlock 锁等动作。
finalize 是基础类 java.lang.Object 的一个方法,它的设计目的是保证对象在被垃圾收集前完成特定资源的回收。finalize 机制现在已经不推荐使用,并且在 JDK 9 开始被标记为 deprecated。

考点分析

这是一个非常经典的 Java 基础问题,我上面的回答主要是从语法和使用实践角度出发的,其实还有很多方面可以深入探讨,面试官还可以考察你对性能、并发、对象生命周期或垃圾收集基本过程等方面的理解。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

Java语言中的final、finally和finalize是三个看似相似但用途完全不同的关键字。final可以修饰类、方法和变量,分别表示不可继承、不可修改和不可重写。finally是Java中确保重要代码一定被执行的机制,通常与try结合使用来保证资源的释放。而finalize是Object类的一个方法,用于在对象被垃圾收集前完成特定资源的回收,但在JDK 9中已被标记为不推荐使用。文章还提到了final关键字的实践意义,如保护只读数据、提高性能等,并强调了不要过度依赖final带来的性能好处。对于finally,建议使用Java 7中添加的try-with-resources语句来更好地处理资源释放。而对于finalize方法,则强调不要使用它来进行资源回收,而是推荐使用try-with-resources或其他替代方法。总的来说,文章从语法、实践和性能等多个方面深入探讨了final、finally和finalize的区别和使用注意事项,对于Java基础知识有很好的总结和指导作用。此外,文章还介绍了final并非immutable的特性,以及finalize存在的问题和替代方案Cleaner的使用建议。文章内容丰富,深入浅出,对读者有很好的指导作用。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《Java 核心技术面试精讲》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(105)

  • 最新
  • 精选
  • WolvesLeader
    能不能帮我分析一哈,匿名内部累,访问局部变量时,局部变量为啥要用final来修饰吗?

    作者回复: 这个因为Java inner class实际会copy一份,不是去直接使用局部变量,final可以防止出现数据一致性问题

    2018-05-10
    4
    175
  • 皮卡皮卡丘
    “将 State 定义为 static,就是为了避免普通的内部类隐含着对外部对象的强引用,因为那样会使外部对象无法进入幻象可达的状态。”这个该怎么理解呢?

    作者回复: 内部类如果不是static,它本身对外面那个类有引用关系,这一点其实从构造阶段就能看出来,你可以写段代码试试;有强引用就是strong reachable状态

    2018-05-10
    52
  • 🎵Children乏
    用final修饰的class,这可以有效避免 API 使用者更改基础功能,某种程度上,这是保证平台安全的必要手段。这个地方真的很需要个例子去帮助理解。比如大家都知道String类是被final修饰不可被继承,但假如没有被final修饰,很好奇会出现什么样不安全的后果。

    作者回复: 谢谢反馈

    2018-05-14
    23
  • Pantheon
    杨老师,关于final不能修改我想请教下,代码如下,class util { public final Integer info = 123; } @Test public void test() throws NoSuchFieldException, IllegalAccessException { util util = new util(); Field field = util.getClass().getDeclaredField("info"); field.setAccessible(true); field.set(util,789); System.out.println(field.get(util)); System.out.println(util.info); } 这里final修饰的被改了,如果不加accessible这句会报错,刚刚试了几个,似乎是基本数据类型改不了,封装类型都能改,请杨老师解答下我的疑惑,感谢。

    作者回复: setAccessible是“流氓”,不问题出在定义为基本数据类型,会被当作constant,可以反编译看看

    2018-05-10
    2
    18
  • ls
    Java中有说:finalize 有一种用途:在 Java 中调用非 Java 代码,在非 Java 代码中若调用了C的 malloc 来分配内存,如果不调用 C 的free 函数,会导致内存泄露。所以需要在 finalize 中调用它。 面试中会有问:为什么 String 会设计成不可变?想听听老师的解释

    作者回复: 是的,很多资源都是需要使用本地方式获取和释放

    2018-05-13
    13
  • Do
    final修饰变量参数的时候,其实理解为内存地址的绑定,这样理解是不是更直观,基本类型指向栈中,引用类型指向堆中。老师后期文章能不能说下java堆栈的区别,还有变量局部变量的生命周期,最好能附上图,加深理解。

    作者回复: 会有

    2018-05-12
    7
  • 张勇
    匿名内部类为什么访问外部类局部变量必须是final的?private Animator createAnimatorView(final View view, final int position) { MyAnimator animator = new MyAnimator(); animator.addListener(new AnimatorListener() { @Override public void onAnimationEnd(Animator arg0) { Log.d(TAG, "position=" + position); } }); return animator; }

    作者回复: 文中介绍了,它其实实现是会copy一份,final可以避免一致性问题

    2018-05-11
    6
  • loveluckystar
    个人理解,finalize本身就是为了提供类似c或c++析构函数产生的,由于java中gc本身就是自动进行的,是不希望被干扰的,(就像System.gc(),并不一定起作用)所以与其费心研究如何使用这个,不如老老实实在finally中把该做的事情做了来的实惠。

    作者回复: 对,有些特别情况需要额外处理,毕竟无法保证编程都按规范来

    2018-05-10
    4
  • 老胡
    Cleaner机制会对jvm回收造成负担,因为gc回收的时候需要检测这个对象十分是Cleaner,然后处理。如果处理过长,十分影响gc的效率。好点方案,容器管理对象,比如spring的sopce,或者对象单利等等,gc负担是一个致命问题,所以Cleaner谨慎使用,甚至应该禁止

    作者回复: 未必有这么可怕,比finalize有数量级的提高,spring这个不错,但不能解决所有场景

    2018-05-11
    3
  • Dee1024
    Cleaner机制没有Finalizer机制那样危险,但仍然是不可预测,也是运行缓慢,同样不能保证他们能够及时执行。所以,尽量避免使用。 正确的关闭资源的打开方式应该是,使用JDK1.7或者以上版本,里面提供的 AutoCloseable 接口,实现该接口以达目的

    作者回复: 同意

    2018-09-13
    2
收起评论
显示
设置
留言
99+
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部