String s=new String("abc")
這行代碼產生了2個對象,一個是new關鍵字建立的new Sring();另外一個是「sdd」對象,abc在一個字符串池中,s 是一個引用變量,指向建立的對象,s自己不是一個對象。html
這個題的考點知識不少:java
引用變量與對象的區別;程序員
字符串文字"abc"是一個String對象,文字池(pool of literal strings)和堆(heap)中的字符串對象。面試
1、引用變量與對象:除了一些早期的Java書籍和如今的垃圾書籍,人們均可以從中比較清楚地學習到二者的區別。
A aa;
這個語句聲明一個類A的引用變量aa[咱們經常稱之爲句柄],而對象通常經過new建立。因此題目中s僅僅是一個引用變量,它不是對象。
2、Java中全部的字符串文字[字符串常量]都是一個String的對象。有人[特別是C程序員]在一些場合喜歡把字符串"看成/當作"字符數組,這也沒有辦法,由於字符串與字符數組存在一些內在的聯繫。事實上,它與字符數組是兩種徹底不一樣的對象。
System.out.println("Hello".length());
char[] cc={'H','i'};
System.out.println(cc.length);
3、字符串對象的建立:
因爲字符串對象的大量使用(它是一個對象,通常而言對象老是在heap分配內存),Java中爲了節省內存空間和運行時間(如比較字符串時,==比equals()快),在編譯階段就把全部的字符串文字放到一個文字池(pool of literal strings)中,而運行時文字池成爲常量池的一部分。文字池的好處,就是該池中全部相同的字符串常量被合併,只佔用一個空間。
咱們知道,對兩個引用變量,使用==判斷它們的值(引用)是否相等,即指向同一個對象:數組
String s1 = "abc" ; String s2 = "abc" ; if( s1 == s2 ) {
System.out.println("s1,s2 refer to the same object");
}else {
System.out.println("trouble");
}
這裏的輸出顯示,兩個字符串文字保存爲一個對象。就是說,上面的代碼只在 pool 中建立了 1 個String對象。
如今看String s = new String("abc");語句,這裏"abc"自己就是pool中的一個對象,而在運行時執行new String()時,
將pool中的對象複製一份放到heap中,而且把heap中的這個對象的引用交給s持有。ok,這條語句就建立了2個String對象。post
String s1 = new String("abc") ; String s2 = new String("abc") ; if( s1 == s2 ){
//不會執行的語句
}
這時用==判斷就可知,雖然兩個對象的"內容"相同(equals()判斷),但兩個引用變量所持有的引用不一樣。學習
補充一個面試題:spa
String str = "aaa" + new String("bbb")建立了幾個String對象?
"aa"一個對象,new Sring()一個對象, "bbb"一個對象, "aa" + new String("bbb");一個對象,共4個對象。code
解釋下字符串池:他是一個由字符組成的一個數組就至關於char str1 =new char[]{a,b,c};
若是不是遇到新的字符串,則直接指向原來的串池,若是遇到新的字符串則建立一個新的串池htm
舉例二
package com.jit.java.test; public class TestStringObject {
public static void main(String[] args) { String str = new String("sdd"); String st = new String("sdd"); //若是不看前面的,光看這一行自己也是建立了2個對象,但sdd在字符串池裏已經有了,因此結合前面的就建立了1個對象new Sring(); } }
//此例一共建立了3個對象。
舉例三
package com.jit.java.test; public class TestStringObject { public static void main(String[] args) { String str = new String("sdd"); String st = new String("sdd"); String st1 = "sdd";//此處沒有建立新的對象,故運行到此仍是3個對象,首先沒new,另外它會去看字符串池中有沒有相同的字符,若是有則st1直接指向sdd,若是不是abc,而是xyz的話則又建立了一個對象 String st2= "sd"; } } //此例一共建立了4個對象