谈谈 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
try {
// do something
System.exit(1);
} finally{
System.out.println(“Print from finally”);
}
上面的finally 里的代码不会被执行
知识扩展
- 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。