final,finally,finalize有什么不同?

Q:谈谈final,finally,finalize有什么不同?

final
final可以用来修饰类、方法、变量,分别有不同的意义。final修饰class表示不能扩展继承,final修饰的方法表示不能重写,final修饰的变量表示不可修改。

推荐使用final关键字来明确表明我们代码的语义,明确告知别人,这是不能修改的。

在并发编程中,final声明的变量可以减少额外的同步开销,和省去防御性拷贝的必要。

注意:final不是不可更改的。具体实例如下:

// 此处的final只能约束strList这个引用不能被赋值,
// 但strList对象行为不被final影响,可以添加元素。
final List strList = new ArrayList<>();
strList.add("Hello");
strList.add("World");
// List.of方法创建的是本身不可变的list
List unmodifiableStrList = List.of("hello", "world");
// 此处的add会抛出异常
unmodifiableStrList.add("again");

immutable
如果要实现不可更改的类,有几种方法。

  1. 将class声明为final
  2. 将所有的成员变量声明为final和private,并且不设置setter方法。
  3. 构造对象时,成员变量是使用深度拷贝来初始化,而不是直接赋值,这是一种防御机制,因为你无法确定输入对象不被其他人修改。

finally
finally是保证重点代码一定被执行的一种机制。使用类似于try-catch-finally或try-finally进行关闭JDBC连接、关锁的动作。

对需要关闭连接资源等,更推荐使用Java7中添加的try-with-resources语句。

finalize
finalize是基础类java.lang.Object的一个方法,已经不推荐使用。你无法保证finalize什么时候执行,是否符合预期。使用不当会影响性能,导致程序死锁、挂起。

finalize被设计成对象在垃圾收集前调用,JVM需要对它进行特殊处理。它拖慢了垃圾收集的速度,导致大量对象堆积,有可能会导致OOM。

幻象引用和引用队列
Java平台目前正在逐步用java.lang.ref.cleaner替换掉finalize实现。cleaner的实现利用了幻象引用,这是一种所谓的post-mortem清理机制。利用幻象引用和引用队列,我们可以保证对象被彻底销毁前做一些类似资源回收的工作。

吸取了finalize里的教训,每个cleaner得到操作都是独立的,有自己的运行线程,可以避免意外死锁的问题。

从可预测性的角度看,cleaner或者幻象引用能够改善的程度仍然是有限的。因此,cleaner适合作为最后的保证手段,不能完全依赖它进行资源回收。

你可能感兴趣的:(final,finally,finalize有什么不同?)