第3讲 | 谈谈final、finally、 finalize有什么不同?
该思维导图由 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-104175 - 皮卡皮卡丘“将 State 定义为 static,就是为了避免普通的内部类隐含着对外部对象的强引用,因为那样会使外部对象无法进入幻象可达的状态。”这个该怎么理解呢?
作者回复: 内部类如果不是static,它本身对外面那个类有引用关系,这一点其实从构造阶段就能看出来,你可以写段代码试试;有强引用就是strong reachable状态
2018-05-1052 - 🎵Children乏用final修饰的class,这可以有效避免 API 使用者更改基础功能,某种程度上,这是保证平台安全的必要手段。这个地方真的很需要个例子去帮助理解。比如大家都知道String类是被final修饰不可被继承,但假如没有被final修饰,很好奇会出现什么样不安全的后果。
作者回复: 谢谢反馈
2018-05-1423 - 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-10218 - lsJava中有说:finalize 有一种用途:在 Java 中调用非 Java 代码,在非 Java 代码中若调用了C的 malloc 来分配内存,如果不调用 C 的free 函数,会导致内存泄露。所以需要在 finalize 中调用它。 面试中会有问:为什么 String 会设计成不可变?想听听老师的解释
作者回复: 是的,很多资源都是需要使用本地方式获取和释放
2018-05-1313 - Dofinal修饰变量参数的时候,其实理解为内存地址的绑定,这样理解是不是更直观,基本类型指向栈中,引用类型指向堆中。老师后期文章能不能说下java堆栈的区别,还有变量局部变量的生命周期,最好能附上图,加深理解。
作者回复: 会有
2018-05-127 - 张勇匿名内部类为什么访问外部类局部变量必须是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-116 - loveluckystar个人理解,finalize本身就是为了提供类似c或c++析构函数产生的,由于java中gc本身就是自动进行的,是不希望被干扰的,(就像System.gc(),并不一定起作用)所以与其费心研究如何使用这个,不如老老实实在finally中把该做的事情做了来的实惠。
作者回复: 对,有些特别情况需要额外处理,毕竟无法保证编程都按规范来
2018-05-104 - 老胡Cleaner机制会对jvm回收造成负担,因为gc回收的时候需要检测这个对象十分是Cleaner,然后处理。如果处理过长,十分影响gc的效率。好点方案,容器管理对象,比如spring的sopce,或者对象单利等等,gc负担是一个致命问题,所以Cleaner谨慎使用,甚至应该禁止
作者回复: 未必有这么可怕,比finalize有数量级的提高,spring这个不错,但不能解决所有场景
2018-05-113 - Dee1024Cleaner机制没有Finalizer机制那样危险,但仍然是不可预测,也是运行缓慢,同样不能保证他们能够及时执行。所以,尽量避免使用。 正确的关闭资源的打开方式应该是,使用JDK1.7或者以上版本,里面提供的 AutoCloseable 接口,实现该接口以达目的
作者回复: 同意
2018-09-132