Java編程思想:第5章 初始化與清理

來源:互聯網
上載者:User

標籤:

隨著電腦革命的發展,“不安全”的編程方式已經逐漸成為編程代價高昂的主因之一。

初始化和清理,正是涉及安全的倆個問題。

5.1 用構造器確保初始化

構造器名與類名相同,沒有傳回值

5.2 方法重載

構造器的重載與方法重載

5.2.1 區分重載的方法

參數列表的不同(不同順序也是重載,但不建議這麼做)

5.2.2 涉及基本類型的重載

  void print(char c){System.out.println("The character is "+c); }
    void print(byte b){System.out.println("The byte is "+b);}
    void print(short s){System.out.println("The short is "+s);}
    void print(int i){System.out.println("The int is "+i);}
    void print(long l){System.out.println("The long is "+l);}
    void print(float f){System.out.println("The float is "+f);}
    void print(double d){System.out.println("The double is "+d); }

1)如果直接傳入數值,如 print(5)則5會被當做 int x = 5; print(x)去尋找最合適的print(int)

2)常量之外的類型會去尋找最合適的類型,沒有同類型,但是有更大類型時會型別提升

3)char是一個特例,如果沒有print(char)則char當做int,執行print(int)

4)需要用cast才能放入小類型的方法裡

5.2.3 用傳回值區分重載方法

void f(){}

int f(){return 1;}

這樣是不可以的,因為很多時候我們不需要傳回值,只是調用而已,那麼我們會寫:

f();這樣是無法區分它是哪個方法的

5.3 預設構造器

如果類裡沒有構造器,編譯器會幫你弄一個。

有了就不會幫你造一個了。

5.4 this關鍵字

可以用於指代調用對象方法時的“當前對象”,可以解決參數和域重名問題。

5.4.1 構造器中調用構造器

this(參數);

必須放於第一行,且最多隻能調用一個。

5.4.2 static的含義

static方法就是沒有this的方法,它屬於類,不屬於對象。

5.5 清理:最終處理和記憶體回收

Java記憶體回收行程負責回收由new建立並且不再被使用的對象。

特殊情況是:如果一個對象以非new方式獲得了一塊記憶體地區,GC就不知道怎麼回收這塊特殊的記憶體。Java提供了finalize()方法,它的工作原理“假定”是這樣的:一旦記憶體回收行程準備好釋放對象佔用的儲存空間,將首先調用finalize()方法, 並且在下一次記憶體回收動作發生時,才會真正回收對象記憶體。所以finalize()方法可以在記憶體回收時做一些重要的清理工作。

//此處疑惑感謝@Launcher的細心解答。

//---------------解答開始

也就是你有這樣一個 class,偽碼:

class A{

   IntPtr m_pBuffer;

    A(){

          m_pBuffer = malloc(1000);

     }

     void finalize(){

               free(_M_pBuffer);

       }
}

A 對象沒有用 new ,而是使用 malloc 獲得了一塊特殊的記憶體區 m_pBuffer。

A a = new A(); // 還是使用 new 獲得對象 A

但是對象 a 本身不用 new 獲得的特殊記憶體區 m_pBuffer,不會被 GC 釋放,所以你需要實現 finalize,在裡面手動釋放。

//---------------解答結束

 

這裡有一個誤區:

finalize() 與 C++中的解構函式(銷毀對象時必須要用到這個函數)相同。

這是不正確的,C++中對象一定會被銷毀,即解構函式一定被調用,而Java裡的對象並不總是被記憶體回收。換句話說:

1)對象可能不被記憶體回收

2)記憶體回收不等於析構

5.5.1 finalize()用途何在

3)記憶體回收只與記憶體有關。

Java中無論對象是如何建立的,GC都會回收它的記憶體,對finalize()的需要限制到一種特殊情況:用了建立對象以外的方式,為對象分配了儲存空間。

之所以要有finalize(),是由於在分配記憶體時可能採用了類似C語言的做法,這種情況主要發生在使用Java調用本地代碼,如用C的malloc()函數系列來分配儲存空間,所以需要在finalize()裡調用本地代碼,使用free()來釋放這些記憶體。

所以不要過多使用finalize(),它不是進行普通清理工作的合適場所。

5.5.2 你必須實施清理

C++中所有對象都會被銷毀。包括局部對象(在棧上建立的)和用new建立的對象(delete調用解構函式)。

Java不允許建立局部對象,必須使用new建立,也沒有delete可用,釋放對象記憶體只能由GC來完成,但是它並不保證一定去回收。如果希望在進行釋放儲存空間之外的清理操作,得明確在finalize()裡使用,這等於析構了,但是沒析構方便。

如果JVM沒有面臨記憶體耗盡的情況,它是不會浪費時間和資源去執行記憶體回收以恢複記憶體的。

5.5.3 終結條件

因為finalize()方法是在記憶體回收前執行的,所以複寫finalize方法可以檢測"邏輯上"的這個對象是否應該被終結。藉此來發現程式中是否有缺陷。如:某對象代表了一個開啟著的檔案,而我們規定這種對象回收時必須為關閉狀態。為了檢測程式是否有缺陷,我們可以複寫finalize方法檢測是否開啟狀態,然後在某次finalize中查看是否存在問題,雖然finalize並不一定會調用,但是只要調用了一次我們就知道是否有問題,這才是關鍵。

我們可以利用System.gc()來建議做GC操作,但JVM有可能不聽我們的。

5.5.4 記憶體回收行程如何工作

 

Java編程思想:第5章 初始化與清理

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.