Java核心-03 谈谈final、finally、 finalize有什么不同?
今天,我要问你的是一个经典的 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 基础问题,我上面的回答主要是从语法和是使用实践角度出发的。面试官还可以考察你对性能、并发、对象生命周期或垃圾收集基本过程等方面的理解。
推荐使用 final 关键字来明确表示我们代码的语义、逻辑意图,这已经被证明在很多场景下是非
常好的实践,比如:
- 我们可以将方法或类声明为final,这样就可以明确告知别人,这些行为是不许修改的。
如果你关注过 Java 核心类库的定义或源码,有没有发现 Java.lang 包下面很多类,相当一部分被声明为 final class?在第三方类库的一些基础类中同样如此,这样可以有效避免 API 使用者更改基础功能,某种程度上,这是保证平台安全的必要手段。
- 使用 final 修饰参数或者变量,也可以清楚地避免意外赋值导致的编程错误,甚至,有人明确推荐将所有方法参数、本地变量、成员变量声明成 final。
- final 变量产生了某种程度的不可变(immutable)的效果,所以,可以用于保护只读数据,尤其是在并发编程中,因为明确地不能再赋值 final 变量,有利于减少额外的同步开销,也可
以省去一些防御性拷贝的必要。
- final 也许会有性能的好处,很多文章或者书籍中都介绍了可在特定场景提高性能,比如,利用final 可能有助于 JVM 将方法进行内联,可以改善编译器进行条件编译的能力等等。坦白说,很多类似的结论都是基于假设得出的,比如现代高性能 JVM(如 HotSpot)判断内联未必依赖final 的提示,要相信 JVM 还是非常智能的。类似的,final 字段对性能的影响,大部分情况下,并没有考虑的必要 。
知识扩展
1. 注意,final 不是 immutable!
我在前面介绍了 final 在实践中的益处,需要注意的是,final 并不等同于 immutable,比如下
面这段代码
final List<String> strList = new ArrayList<>();
strList.add("Hello");
strList.add("world");
List<String> unmodifiableStrList = List.of("hello", "world");
unmodifiableStrList.add("again");
final 只能约束 strList 这个引用不可以被赋值,但是 strList 对象行为不被 final 影响,添加元素
等操作是完全正常的。如果我们真的希望对象本身是不可变的,那么需要相应的类支持不可变的
行为。在上面这个例子中,List.of 方法创建的本身就是不可变 List,最后那句 add 是会在运行
时抛出异常的。
Immutable 在很多场景是非常棒的选择,某种意义上说,Java 语言目前并没有原生的不可变支
持,如果要实现 immutable 的类,我们需要做到:
- 将 class 自身声明为 final,这样别人就不能扩展来绕过限制了。
- 将所有成员变量定义为 private 和 final,并且不要实现 setter 方法。
- 通常构造对象时,成员变量使用深度拷贝来初始化,而不是直接赋值,这是一种防御措施,
因为你无法确定输入对象不被其他人修改。 - 如果确实需要实现 getter 方法,或者其他可能会返回内部状态的方法,使用 copy-on-write
原则,创建私有的 copy。
关于 setter/getter 方法,很多人喜欢直接用 IDE 一次全部生成,建议最好是你确定有需要时再
实现。
Java核心-03 谈谈final、finally、 finalize有什么不同?的更多相关文章
- 谈谈 final finally finalize 区别
声明 本篇所涉及的提问,正文的知识点,全都来自于杨晓峰的<Java核心技术36讲>,当然,我并不会全文照搬过来,毕竟这是付费的课程,应该会涉及到侵权之类的问题. 所以,本篇正文中的知识点, ...
- 谈谈final, finally, finalize的区别
final 修饰符(关键字)如果一个类被声明为final,意味着它不能再派生出新的子类,不能作为父类被继承.因此一个类不能既被声明为 abstract的,又被声明为final的.将变量或方法声明为fi ...
- java面试题之final、finalize和finally的区别
finally:finally是一个关键字,与try和catch一起用于异常的处理,finally块一定会执行,无论在try快中是否有发生异常. finalize:finalize方法是在对象被回收之 ...
- Java核心-01 谈谈你对Java平台的理解
今天我要问你的问题是,谈谈你对 Java 平台的理解?“Java 是解释执行”,这句话正确吗? 典型回答 Java本身是一种面向对象的语言,最显著的特性有两个.一是所谓的“书写一次,到处运行”,能够非 ...
- Java 核心内容相关面试题【2】
第一,谈谈final, finally, finalize的区别. final?修饰符(关键字)如果一个类被声明为final,意味着它不能再派生出新的子类,不能作为父类被继承.因此一个类不能既被声明为 ...
- 分享13道上海尚学堂拿回来的Java面试真题,这些都是Java核心常见问题,想拿OFFER必看!
上海尚学堂Java培训学员参加面试带回来的真题,分享出来与大家,希望大家能认真地看看做一遍.后面有详细题解答案,对照下,看看自己做得怎么样,把这些面试遇到的真题全部掌握,做好面试笔试前的准备. 一.1 ...
- java面试题(杨晓峰)---第三讲谈谈final、finally、finalize有什么不同?
java语言有很多看起来相似,但用途却完全不相同的语言要素,这些内容往往容易成为面试官考察你知识掌握程度的切入点. 今天我要问你一个基础的java经典题目,谈谈final.finally.finali ...
- Java基础知识总结--final、finally、finalize的区别
谈谈final.finally.finalize的区别 1.final修饰符:如果一个类被声明为final,意味着这个类不能再被派生出新的子类,不能作为父类被别的类继承.因此,一个类不能即被声明为ab ...
- 【Java面试题系列】:Java中final finally finalize的区别
本篇为[Java面试题系列]第三篇,文中如有错误,欢迎指正. 第一篇链接:[Java面试题系列]:Java基础知识常见面试题汇总 第一篇 第二篇链接:[Java面试题系列]:Java基础知识常见面试题 ...
随机推荐
- iOS7 AVAudioRecorder不能录音
今天写录音代码的时候,在iOS7以下就可以录音,但是iOS7上不可以,后来才知道iOS7录音方式变了,加上下面的代码就可以了,bingo AVAudioSession *audioSession = ...
- python入门 类的继承和聚合(五)
继承 class Rocket: def __init__(self, name, distance): self.name = name self.distance = distance def l ...
- Perl 数组应用详解(push, pop, shift, unshift)
Perl的数组操作有四大常用函数: push:从数组的末尾加入元素.pop :从数组的末尾取出元素 shift: 从数组的开头取出元素unshift:从数组的开头加入元素 1.push #!/usr/ ...
- 牛客B-Xor Path /// 求所有Path( i->j )( j >= i )路径的异或和
题目大意: https://ac.nowcoder.com/acm/contest/272/B?&headNav=acm 给定一棵n个点的树,每个点有权值.定义表示 到 的最短路径上,所有 ...
- java编程——数据的加法
设计思想: 第一步:从键盘上输入一定个数的整数. 第二步:因为在main()方法中的参数是String类型的,所以第一步中输入的其实是字符类型,在这一步要把String转化成int. 第三步:初始化s ...
- 数据库MySQL--修改数据表
创建数据库::create database 数据库名: 如果数据不存在则创建,存在不创建:Create database if not exists 数据库名 ; 删除数据库::drop datab ...
- Android开发 解决Installation failed due to XXX 问题
报错信息 Android studio 安装app的时候以下报错 Installation did not succeed. The application could not be installe ...
- Google Projectsheet Planning 插件的WBS
生成 WBS的序列號 在 Sldebar中的 "WBS" 按鈕: "< WBS" 取消下級目錄 "WBS >" 生成下級目錄 G ...
- Apocalypse Someday
Apocalypse Someday 定义一个数是合法的,当且仅当中间出现至少一个连续的大于三个的6,求第x个合法的数,\(x\leq 50,000,000\) 解 首先,注意到求第几个,即想到试填法 ...
- Windows 关闭win32 控制台
{ fclose(pf); BOOL ret = FreeConsole(); }