Java 對象句柄

每種編程語言都有自己的數據處理方式。有些時候,程序員必須時刻留意準備處理的是什麼類型。您曾利用一些特殊語法直接操作過對象,或處理過一些間接表示的對象嗎(C或C++裏的指針)?
      所有這些在Java裏都得到了簡化,任何東西都可看作對象。因此,我們可採用一種統一的語法,任何地方均可照搬不誤。但要注意,儘管將一切都“看作”對 象,但操縱的標識符實際是指向一個對象的“句柄”(Handle,也就是包裝類的申明)。在其他Java參考書裏,還可看到有的人將其稱作一個“引用”, 甚至一個“指針”。可將這一情形想象成用遙控板(句柄)操縱電視機(對象)。只要握住這個遙控板,就相當於掌握了與電視機連接的通道。但一旦需要“換頻 道”或者“關小聲音”,我們實際操縱的是遙控板(句柄),再由遙控板自己操縱電視機(對象)。如果要在房間裏四處走走,並想保持對電視機的控制,那麼手上 拿着的是遙控板,而非電視機。
       此外,即使沒有電視機,遙控板亦可獨立存在。也就是說,只是由於擁有一個句柄,並不表示必須有一個對象同它連接。所以如果想容納一個詞或句子,可創建一個String句柄:
      String s;
      但這裏創建的只是句柄,並不是對象。若此時向s發送一條消息,就會獲得一個錯誤(運行期)。這是由於s實際並未與任何東西連接(即“沒有電視機”)。
       需要注意的是:主類型的數據成員可直接初始化,是變量,不是句柄。
       String s; 創建的只是句柄,並不是對象。若此時向s發送一條消息,就會獲得一個錯誤(運行期),這是由於s實際並未與任何東西連接。因此,一種更安全的做法是:創建一個句柄時,記住無論如何都進行初始化:
       String s = "asdf";
      然而,這裏採用的是一種特殊類型:字串可用加引號的文字初始化。通常,必須爲對象使用一種更通用的初始化類型。創建句柄時,通常用new關鍵字達到這一目的。new的意思是:“把我變成這些對象的一種新類型”。
       String s = new String("abc");它不僅指出“將我變成一個新字串”,也通過提供一個初始字串,指出了“如何生成這個新字串”。
        這裏在堆(heap)中創建一個string 對象,還會在文字池(string pool)裏面創建一個"abc"對象;s是這個對象的引用變量(句柄),它不是對象,對象一般通過new創建。

字符串對象的創建:
由 於字符串對象的大量使用(它是一個對象,一般而言對象總是在heap分配內存),Java中爲了節省內存空間和運行時間,在編譯階段就把所有的字符串文字 放到一個文字池(pool of literal strings)中,而運行時文字池成爲常量池的一部分。文字池的好處,就是該池中所有相同的字符串常量被合併,只佔用一個空間。
我們知道,對兩個引用變量,使用==判斷它們的值(引用)是否相等,即指向同一個對象:
這裏 s1 == s2 成立  //因爲比較的不是句柄,而是內容
String s = new String("abc") ; 在編譯階段在文字池中創建“abc”對象,運行new時,將pool中的對象複製一份放到heap中,並且把heap中的這個對象的引用交給s持有,因此這條語句創建了2個String對象。

Java代碼 

String s1 = "abc" ;  
String s2 = "abc" ;   

這裏 s1 == s2 不成立,s1.equals(s2)成立  //因爲比較的是句柄,內容雖然相同但句柄不同
上面的代碼創建了幾個String Object? (三個,pool中一個,heap中2個。)

 

參考來源:
1.http://zhidao.baidu.com/question/15950414.html
2.http://blog.sina.com.cn/s/blog_4b622a8e0100c28z.html

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