finalize方法之对象的自我拯救

finalize是Object中的一个方法

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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
/**
* 对象的自我拯救
* 被拯救后的对象信息丢失,但是对象的地址值不变
*
* @author ZZQ
*/
public class FinalizeEscapeGC {
private String name;
public static FinalizeEscapeGC SAVE_HOOK = null;

/**
* 判断是否还活着
*/
public void isAlive() {
System.out.println(SAVE_HOOK.name + "还活着");
}

@Override
protected void finalize() throws Throwable {
super.finalize();
System.out.println("finalize方法执行了");
// 与对象建立联系,自救
FinalizeEscapeGC.SAVE_HOOK = this;
}

public static void main(String[] args) throws InterruptedException {
SAVE_HOOK = new FinalizeEscapeGC();
SAVE_HOOK.name = "zzq";
System.out.println("被拯救前对象地址值:" + SAVE_HOOK);

//第一次自救
SAVE_HOOK = null;
System.gc();
//因为finalize的优先级低,先等一下
Thread.sleep(500);
if (SAVE_HOOK != null) {
SAVE_HOOK.isAlive();
} else {
System.out.println("第一次自救失败");
}
System.out.println("被拯救后对象地址值:" + SAVE_HOOK);
//第二次自救
//因为每个对象的finalize()方法只会被系统自动调用一次,所以第一次调用后,
//第二次自救时不会再调用finalize(),自然也就不会与其他的对象产生联系,从而自救失败
SAVE_HOOK = null;
System.gc();
//因为finalize的优先级低,先等一下
Thread.sleep(500);
if (SAVE_HOOK != null) {
SAVE_HOOK.isAlive();
} else {
System.out.println("第二次自救失败");
}
}
//finalize()虽然能够实现对象自救,但是不要轻易使用,因为他的运行代价太大,不确定性高,无法确定各个对象的调用顺序。
//而且finalize()能做的事,try-finally都能做,而且做得更好
}