在Java里,任何東西都可看作對象。盡管將一切都“看作”對象,但操縱的標識符實際是指向一個對象的“句柄”(Handle),有的人將其稱作一個“引用”,甚至一個“指針”。
主類型的數據成員可直接初始化,是變量,不是句柄。
String s; 創建的只是句柄,並不是對象。若此時向s發送一條消息,就會獲得一個錯誤(運行期),這是由於s實際並未與任何東西連接。
創建句柄時,我們希望它同一個新對象連接。通常用new關鍵字達到這一目的。new的意思是:“把我變成這些對象的一種新類型”。
String s = new String("asdf");它不僅指出“將我變成一個新字串”,也通過提供一個初始字串,指出了“如何生成這個新字串”。
String s = new String("xx");
這里在堆(heap)中創建一個string 對象,還會在文字池(string pool)里面創建一個"abc"對象;s是這個對象的引用變量(句柄),它不是對象,對象一般通過new創建。
字符串對象的創建:
由於字符串對象的大量使用(它是一個對象,一般而言對象總是在heap分配內存),Java中為了節省內存空間和運行時間,在編譯階段就把所有的字符串文字放到一個文字池(pool of literal strings)中,而運行時文字池成為常量池的一部分。文字池的好處,就是該池中所有相同的字符串常量被合並,只占用一個空間。
我們知道,對兩個引用變量,使用==判斷它們的值(引用)是否相等,即指向同一個對象:
String s1 = "abc" ;
String s2 = "abc" ;
這里 s1 == s2 成立 //因為比較的不是句柄,而是內容
String s = new String("abc") ; 在編譯階段在文字池中創建“abc”對象,運行new時,將pool中的對象復制一份放到heap中,並且把heap中的這個對象的引用交給s持有,因此這條語句創建了2個String對象。
String s1 = new String("abc") ;
String s2 = new String("abc") ;
這里 s1 == s2 不成立,s1.equals(s2)成立 //因為比較的是句柄,內容雖然相同但句柄不同
上面的代碼創建了幾個String Object? (三個,pool中一個,heap中2個。)
轉自:http://blog.sina.com.cn/s/blog_4b622a8e0100c28z.html