《Thinking In Java(3rd)》--一切皆對象

用引用(reference)操縱對象

在java中一切都被視爲對象,因此可採用單一固定的語法。儘管一切都“看做”對象,但操作的標識符實際上是對象的一個“引用(reference)”。你可以將這一情形想象成用遙控器(引用)來操作電視機(對象)。你只要握住這個遙控器,就能保持與電視機的連接。當有人想改變頻道或減小音量時,你實際操控的是遙控器(引用),再由遙控器來調控電視機(對象)。如果你想在房間裏四處走走,同時仍能調控電視機;那麼你只需攜帶遙控器(引用)而不是電視機(對象)。


此外,即時沒有電視機,遙控器亦可獨立存在。也就是說,你擁有一個引用,並不一定需要有一個對象與它關聯。因此,如果你想操作一個詞或句子,你可以創建一個String引用: String s;

但這裏所創建的只是引用,並不是對象。如果此時想s發送一個消息,就會返回一個運行時錯誤。這是因爲此時s實際上沒有與任何事物關聯(即沒有電視機)。因此,一種安全的做法是: 創建一個引用的同時便進行初始化: String s = "Hello World!";

但這裏用到了Java語言的一個特性:字符串可以帶引號的文本初始化。通常,你必須對對象使用一種更通用的初始化方法。


創建對象

一旦創建了一個引用,就希望它能與一個新的對象相連接。我們通常用new關鍵字來實現這一目的。new關鍵字的意思是:“給我一個對象。”所以前面的例子可以寫成:String s = new String("Hello World");

它不僅表示“給我一個新的字符串”,而且通過提供一個初始化字符串,給出了怎樣產生這個String的信息。


存儲到什麼地方

程序運行時,有六個不同的地方可以存儲數據:

1、寄存器(register):這是最快的存儲區,因爲他位於不同於其他的地方——處理器內部。但是寄存器的數量極其有限,所以寄存器由編譯器根據需求進行分配。你不能直接控制,也不能在程序中感覺到寄存器存在的任何跡象。

2、堆棧(stack):位於通用RAM(random-access memory,隨機訪問存儲器)中,但通過它的“堆棧指針”可以從處理器那裏獲得直接支持。堆棧指針若向下移動,則分配新的內存;若向上移動,則釋放那些內存。這是一種快速有效的分配存儲方法,僅次於寄存器。創建程序時,Java編譯器必須知道存儲在堆棧內所有數據的確切大小和生命週期,因爲它必鬚生成相應的代碼,以便上下移動堆棧指針。這一約束限制了程序的靈活性,所以雖然某些Java數據存儲於堆棧中——特別是對象引用,但是Java對象並不存儲於其中。

3、堆(heap):一種通用性的內存池(也存在於RAM中),用於存儲所有的Java對象。堆不同於堆棧的好處是:編譯器不需要知道要從堆裏分配多少存儲區域,也不知道存儲的數據在堆裏存活多長時間。因此,因此在堆裏分配存儲有很大的靈活性。當你需要創建一個對象時,只需用new寫一行簡單的代碼,當執行這行代碼時,會自動在堆裏進行存儲分配。當然,爲這種靈活性必須要付出相應的代價。用堆進行存儲分配比用堆棧存儲分配需要更多的時間。

4、靜態存儲(static storage):這裏的“靜態”是指“在固定的位置”(儘管也在RAM裏)。靜態存儲裏存放程序運行時一直存在的數據。你可以用關鍵字static來標識一個對象的特定元素是靜態的,但Java對象本身從來不會存放在靜態存儲空間裏。

5、常量存儲(constant storage):常量值通常直接存放在程序代碼內部,這樣做是安全的,因爲它們永遠不會改變。有時,在嵌入式系統中,常量本身會和其他部分隔離開,所以在這種情況下,可以選擇將其存放在ROM(read-only memory,只讀存儲器)中。

6、非RAM存儲(non-RAM storage):如果數據完全存活於程序之外,那麼它可以不受程序的任何控制,在程序沒有運行時也可以存在。其中兩個基本的例子就是“流對象(streamed object)”和“持久化對象(persistent object)”。在“流對象”中,對象轉化成字節流,通常被髮送到另一臺機器。在“持久化對象”中,對象被存放於磁盤上,因此,即時程序終止,它們仍可以保存自己的狀態。這種存儲方式的技巧在於:把對象轉化成可以存放在其他媒介上的事物,在需要時,可恢復成常規的、基於RAM的對象。Java提供輕量級持久化(lightweight  persistent)的支持,未來的Java版本可能會爲持久化提供更全面的解決方案。



對象作用域(scope of object)

Java對象不具備和基本類型一樣的生命週期。當創建一個對象時,它可以存活於作用域之外。代碼如下:

{

String str = "hello world!!";

}

引用str在作用域終點就消失了。然而,str指向的String對象仍繼續佔據內存空間。事實證明,由new 創建的對象,只要你需要,就會一直保留下去。但在Java中有一個“垃圾回收器”,用來監視用new創建的所有對象,並辨別那些不會再被引用的對象。隨後,釋放這些對象的內存空間,以便供其他新的對象使用。也就是說:你根本不必擔心內存回收的問題。你只需要創建對象,一旦不再需要,它們就會自動消失。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章