1. 程式人生 > >《java程式設計思想》第四版 第2 章 一切都是物件 2 . 3 絕對不要清除物件

《java程式設計思想》第四版 第2 章 一切都是物件 2 . 3 絕對不要清除物件

在大多數程式設計語言中,變數的“存在時間”(Lifetime)一直是程式設計師需要著重考慮的問題。變數應持 續多長的時間?如果想清除它,那麼何時進行?在變數存在時間上糾纏不清會造成大量的程式錯誤。在下面 的小節裡,將闡示Java 如何幫助我們完成所有清除工作,從而極大了簡化了這個問題。

2 . 3 . 1 作用域

大多數程式設計語言都提供了“作用域”(Scope)的概念。對於在作用域裡定義的名字,作用域同時決定了 它的“可見性”以及“存在時間”。在C,C++和Java 裡,作用域是由花括號的位置決定的。參考下面這個 例子:

{
int x = 12;
/* only x available */
{ int q = 96; /* both x & q available */ } /* only x available */ /* q “out of scope” */ }

作為在作用域裡定義的一個變數,它只有在那個作用域結束之前才可使用。 在上面的例子中,縮排排版使Java 程式碼更易辨讀。由於Java 是一種形式自由的語言,所以額外的空格、制 表位以及回車都不會對結果程式造成影響。 注意儘管在C 和C++裡是合法的,但在Java 裡不能象下面這樣書寫程式碼:

int x = 12;
{
int x = 96; /* illegal */
}
}

編譯器會認為變數x 已被定義。所以C 和C++能將一個變數“隱藏”在一個更大的作用域裡。但這種做法在 Java 裡是不允許的,因為Java 的設計者認為這樣做使程式產生了混淆。

2 . 3 . 2 物件的作用域

Java 物件不具備與主型別一樣的存在時間。用new 關鍵字建立一個Java 物件的時候,它會超出作用域的範 圍之外。所以假若使用下面這段程式碼:

{
String s = new String("a string");
} /* 作用域的終點 */

那麼控制代碼s 會在作用域的終點處消失。然而,s 指向的String 物件依然佔據著記憶體空間。在上面這段程式碼 裡,我們沒有辦法訪問物件,因為指向它的唯一一個控制代碼已超出了作用域的邊界。在後面的章節裡,大家還 會繼續學習如何在程式執行期間傳遞和複製物件控制代碼。 這樣造成的結果便是:對於用new 建立的物件,只要我們願意,它們就會一直保留下去。這個程式設計問題在C 和C++裡特別突出。看來在C++裡遇到的麻煩最大:由於不能從語言獲得任何幫助,所以在需要物件的時候, 根本無法確定它們是否可用。而且更麻煩的是,在C++裡,一旦工作完成,必須保證將物件清除。 這樣便帶來了一個有趣的問題。假如Java 讓物件依然故我,怎樣才能防止它們大量充斥記憶體,並最終造成程 序的“凝固”呢。在C++裡,這個問題最令程式設計師頭痛。但Java 以後,情況卻發生了改觀。Java 有一個特別 的“垃圾收集器”,它會查詢用new 建立的所有物件,並辨別其中哪些不再被引用。隨後,它會自動釋放由 那些閒置物件佔據的記憶體,以便能由新物件使用。這意味著我們根本不必操心記憶體的回收問題。只需簡單地 建立物件,一旦不再需要它們,它們就會自動離去。這樣做可防止在C++裡很常見的一個程式設計問題:由於程 序員忘記釋放記憶體造成的“記憶體溢位”。