</pre>finalize()——“特殊”垃圾回收器<pre name="code" class="java">
finalize()用来释放非new对象的内存。它的工作原理“假定”是这样的:一旦垃圾回收器准备好释放对象占用的存储空间,将首先调用finalize()方法,并且在下一次垃圾回收动作发生时,才会真正的回收对象占用的内存。
注意:finalize()不是c++中的析构函数,在c++中,对象一定会被销毁(如果程序没有缺陷的话);而在java中的对象却不一定总是被垃圾回收。
Java中没有提供“析构函数”或相似的概念,所以要做类似的清理动作,需要自己手动创建一个执行清理工作的普通方法。
finalize()的真正的用途:
1.对象可能不被垃圾回收
2.垃圾回收并不等于“析构”
3.垃圾回收只与内存有关
4.如果java虚拟机(JVM)没有面临内存耗尽的情况,他是不会浪费时间去执行垃圾回收来恢复内存的。
5.finalize()不一定会发生,所以必须创建其他的“清理”方法,并调用。
<span style="font-size:18px;">package finalizetest;
class Book{
boolean checkedOut = false;
Book( boolean checkOut){
checkedOut = checkOut;
}
void checkIn(){
checkedOut = false;
}
protected void finalize(){
if(checkedOut)
System.out.println("Error:cheched out");
try {
super.finalize();
System.out.println("use finalize().");
} catch (Throwable e) {//抛出异常
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public class finalizetest {
public static void main(String [] args){
Book story = new Book(true);
story.checkIn();
new Book(true);
System.gc();//提交回收申请
}
}
</span>
<span style="font-size:18px;">//输出
Error:cheched out
use finalize()</span>
System.gc()//只是提交申请,但实际上finalize()执不执行,什么时候执行都是未知。
system.gc)()提交申请之后执行finalize()方法,并且输出两个句子,由于第二个创建的对象没有checkin,所以它的空间也没有被释放,直到程序结束的时候变成无引用的对象。那么为什么没有输出,我可以理解为因为程序结束了,所以输不出来吗?
每当程序结束的时候,垃圾回收站都会默默的出来收拾残局,而system.gc()是申请调用finalize()方法,这个时候,被我们重载过的方法就会被使用并输出语句。
<span style="font-size:18px;">public class FinalizationDemo {
public static void main(String[] args) {
Cake c1 = new Cake(1);
Cake c2 = new Cake(2);
Cake c3 = new Cake(3);
c2 = c3 = null;//回收
System.gc();
}
}
class Cake extends Object {
private int id;
public Cake(int id) {
this.id = id;
System.out.println("Cake Object " + id + "is created");
}
protected void finalize() throws java.lang.Throwable {
super.finalize();
System.out.println("Cake Object " + id + "is disposed");
}
}
</span>
<span style="font-size:18px;">//输出
C:\1>java FinalizationDemo
Cake Object 1is created
Cake Object 2is created
Cake Object 3is created
Cake Object 3is disposed
Cake Object 2is disposed</span>
2,3的销毁可以看出finalize()无法确切地保证垃圾回收器何时调用该方法,也无法保证调用不同对象的方法的顺序。