典型回答

final 可以用来修饰类、方法、变量,分别有不同的意义;

  • final 修饰的 class 代表不可以继承扩展
  • final 的变量是不可以修改的
  • final 的方法是不可以重写的(override)
  • final 修饰方法参数,不能修改参数值,否则编译报错。

finally 是Java保证代码一定要被执行的一种机制。
我们可以使用 try-finally 或者 try-catch-finally 来进行类似关闭 JDBC 连接、保证 unlock 锁等动作。

finalize 是Object的一个方法,保证对象在被垃圾收集前完成特定资源的回收。
finalize 机制现在已经不推荐使用,并且在JDK9开始被标记为depretected

考点分析

推荐使用 final 关键字来明确表示我们代码的语义,逻辑意图,比如:

  1. 将方法或者类声明为 final,明确告诉别人,这些行为是不需修改的。
  2. 使用final修饰参数或者变量,可以清楚的避免意外赋值导致的编程错误。
  3. final 变量产生了某种程度的不可变(immutable)的效果,所以,可以用于保护只读数据,尤其是在并发编程中。

从开发实践的角度,我不想过度强调这一点,这是和 JVM 的实现很相关的,未经验证比较难以把握。我的建议是,在日常开发中,除非有特别考虑,不然最好不要指望这种小技巧带来的所谓性能好处,程序最好是体现它的语义目的。

finally,知道怎么用,关闭连接资源等,推荐使用 try-weith-resource

  1. try {
  2. // do something
  3. System.exit(1);
  4. } finally{
  5. System.out.println("Print from finally");
  6. }

对于finalize, 明确它是不推荐使用的,因为无法保证 finalize 什么时候执行,执行的是否符合预期。使用不当会影响性能,导致程序死锁,挂起等。

知识扩展

注意,final 不是 immutable!

  1. final List<String> strList = new ArrayList<>();
  2. strList.add("Hello");
  3. strList.add("world");
  4. List<String> unmodifiableStrList = List.of("hello", "world");
  5. unmodifiableStrList.add("again");

final 只能约束 strList 这个引用不可以被赋值,但是 strList 对象行为不被 final 影响,添加元素等操作完全正常。而 List.of() 方法(jdk9+)创建的本身就是不可变 List,最后那句 add 会抛出运行时异常。

资源用完即显示释放,或者利用资源池来尽量重用。

finalize 是如此的不堪~

实践中,因为 finalize 拖慢垃圾收集,导致大量对象堆积,也是一种典型的导致 OOM 的原因。