谈谈final,finally,finalize的区别

谈谈final,finally,finalize的区别

一月 03, 2020

final,finally,finalize之间一点关系都没有,仅仅是长的像!

final 表示不可修改的,可以用来修饰类,方法,变量。

final修饰class表示该class不可以被继承。
final修饰方法表示方法不可以被overrride(重写)。
final修饰变量表示变量是不可以修改。
一般来说推荐将本地变量,成员变量,固定的静态变量用final修饰,明确是不可以被修改的。

finally是Java的异常处理机制中的一部分

finally块的作用就是为了保证无论出现什么情况,finally块里的代码一定会被执行。
一般来说在try-catch-finally 来进行类似关闭 JDBC连接,释放锁等资源的操作。
另外扩展一下,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
public static String test() {
String str = null;
int i = 0;
if (i == 0) {
return str;//直接返回未执行到finally语句块
}
try {
System.out.println("try...");
return str;
} finally {
System.out.println("finally...");
}
}

public static String test2() {
String str = null;
int i = 0;
i = i / 0;//抛出异常未执行到finally语句块
try {
System.out.println("try...");
return str;
} finally {
System.out.println("finally...");
}
}

public static String test3() {
String str = null;
try {
System.out.println("try...");
System.exit(0);//系统退出未执行到finally语句块
return str;
} finally {
System.out.println("finally...");
}
}

final修饰的List,不会影响其行为:

1
2
3
4
5
final List<String> strList = new ArrayList<>();
strList.add("Hello");
strList.add("World");
List<String> unModifiedStrList=List.of("Hello","World");
unModifiedStrList.add("more");

final只能约束strList这个引用不可以被赋值,但是strList对象行为不被final影响,添加元素的操作是完全正常的。如果我们真的希望对象本身是不可变的,那么需要相应的类支持不可变的行为。
在上面的例子中,List.of方法创建的就是不可变List,最后那句add会在运行时抛出异常。

finalize是Object类的一个方法,是GC进行垃圾回收前要调用的一个方法。

我们要明确它是不推荐使用的,业界实践一再证明它不是个好的办法,在 Java 9 中,甚至明确将 Object.finalize() 标记为 deprecated!如果没有特别的原因,不要实现 finalize 方法,也不要指望利用它来进行资源回收。
为什么呢?简单说,你无法保证 finalize 什么时候执行,执行的是否符合预期。使用不当会影响性能,导致程序死锁、挂起等。
通常来说,利用上面的提到的 try-with-resources 或者 try-finally 机制,是非常好的回收资源的办法。如果确实需要额外处理,可以考虑 Java 提供的 Cleaner 机制或者其他替代方法。