1. 程式人生 > >thinking in java test5.5練習(10)(11)(12)finalize()方法

thinking in java test5.5練習(10)(11)(12)finalize()方法

原文地址: http://blog.csdn.net/qq_35396447/article/details/52411439
練習(10):編寫具有finalize()方法的類,並在方法中列印訊息。在main()中為該類建立一個物件。試解釋這個程式的行為。
我們知道java有垃圾回收機制,垃圾回收機制會在必要的時刻回收記憶體。但是要注意的是,垃圾回收器只知道釋放那些由new分配的記憶體。程式有時候會存在某些特殊的記憶體,不是由new獲得的,此時垃圾回收器就無法對其清理。這時候finalize()方法就起作用了。
如果一個類中有finalize()方法,當垃圾回收器準備釋放物件的記憶體時,會先呼叫finalize()方法,通過裡面你寫的程式碼進行一些工作,比如檢查某些資源是否清理等等,然後在下一次垃圾回收器的回收動作時再回收物件。
程式碼:

public class test5_5_10 {
public static void main(String[] args){
DownloadPicture down = new DownloadPicture();
down.closeInternet();
new DownloadPicture();
//由於真實情況很難碰到記憶體不夠用,所以用該程式碼來強行中止程式動作,
// 達到模擬垃圾回收器回收該物件的目的
System.gc();
}
}

class DownloadPicture{
boolean isClose = false;

void closeInternet(){
    isClose = true;
}

@Override
protected void finalize() throws Throwable {
    super.finalize();
    if (!isClose){//如果網路沒有關閉,則發出警告
        System.err.println("internet is not close");
    }
}

}

這裡是一個模擬下載類,我們知道下載需要連線網路,當下載完畢後需要關閉掉那些連線網路的資源,這個類裡closeInternet()方法是用來關閉那些資源的。在main裡我們可以看到,新new的一個物件沒有關閉資源。這時如果我們沒有重寫finalize()方法,那麼即使新new出來的物件被回收,這些資源也許會一直佔用著。所以我們在finalize方法裡做了檢查工作。

練習(11):修改前一個練習的程式,讓你的finalize()總會被呼叫。
上一個程式例子中我們模擬了網路連結的情況,但在真實連結中自然會有其它方法來關閉那些需要關閉的資源。因為在通常情況下我們不能指望finalize()。finalize()不是適合進行普通清理的方式。
這裡題目出的有點問題,finalize()在垃圾回收器回收到相應物件時總會被呼叫,這裡的總會被呼叫意思時在我們寫的模擬程式碼中總會被呼叫,其實就是這句程式碼:

System.gc();
1
練習(12):編寫名為Tank的類,此類的狀態可以是“滿的”或“空的”。其終結條件是:物件被清理時必須處於空狀態。請編寫finalize()以檢驗終結條件是否成立。在main()中測試Tank可能發生的幾種使用方式。

public class test5_5_12 {
public static void main(String[] args){
//預設為滿的並且清理
Tank tank = new Tank(“tank”);
tank.clear();
//預設為滿的且不清理
// Tank tank1 = new Tank(“tank1”);這種寫法System.gc()無法生效。
new Tank(“tank1”);
//預設為空且不清理
new Tank(“tank2”,false);
//預設為空並且清理
Tank tank3 = new Tank(“tank3”,false);
tank3.clear();

    System.gc();//使達到垃圾回收狀態
}

}

class Tank{
boolean empty ;
String name;
public Tank(String name){
this.name = name;
empty = true;//預設為滿的
}

public Tank(String name,boolean isEmpty){//構造方法
    this.name = name;
    empty = isEmpty;
}

void clear(){//使狀態變成空
    empty = false;
}

@Override
protected void finalize() throws Throwable {
    super.finalize();
    if (empty){
        System.err.println("tank : " + name + " is empty");
    }
}

}

輸出結果是tank1狀態為滿的,不滿足清理條件。