標籤:
String類是final的,String類其實是通過char數組來儲存字串的。對String對象的任何改變都是重建新的對象,原對象不動。
1)對於直接相加字串,效率很高,因為在編譯器便確定了它的值,也就是說形如"I"+"love"+"java"; 的字串相加,在編譯期間便被最佳化成了"Ilovejava"。
對於間接相加(即包含字串引用),形如s1+s2+s3; 效率要比直接相加低,因為在編譯器不會對引用變數進行最佳化。
2)String、StringBuilder、StringBuffer三者的執行效率:
StringBuilder > StringBuffer > String
當然這個是相對的,不一定在所有情況下都是這樣。
比如String str = "hello"+ "world"的效率就比 StringBuilder st = new StringBuilder().append("hello").append("world")要高。
因此,這三個類是各有利弊,應當根據不同的情況來進行選擇使用:
當字串相加操作或者改動較少的情況下,建議使用 String str="hello"這種形式;
當字串相加操作較多的情況下,建議使用StringBuilder,如果採用了多線程,則使用StringBuffer。
面試題:
1. 下面這段代碼的輸出結果是什嗎?
String a = "hello2"; String b = "hello" + 2; System.out.println((a == b));
輸出結果為:true。原因很簡單,"hello"+2在編譯期間就已經被最佳化成"hello2",因此在運行期間,變數a和變數b指向的是同一個對象。
2.下面這段代碼的輸出結果是什嗎?
String a = "hello2"; String b = "hello"; String c = b + 2; System.out.println((a == c));
輸出結果為:false。由於有符號引用的存在,所以 String c = b + 2;不會在編譯期間被最佳化,不會把b+2當做字面常量來處理的,因此這種方式產生的對象事實上是儲存在堆上的。因此a和c指向的並不是同一個對象。
3.下面這段代碼的輸出結果是什嗎?
String a = "hello2"; final String b = "hello"; String c = b + 2; System.out.println((a == c));
輸出結果為:true。對於被final修飾的變數,會在class檔案常量池中儲存一個副本,也就是說不會通過串連而進行訪問,對final變數的訪問在編譯期間都會直接被替代為真實的值。那麼String c = b + 2;在編譯期間就會被最佳化成:String c = "hello" + 2;
4.String str = new String("abc")建立了多少個對象?
而這道題目讓人混淆的地方就是這裡,這段代碼在運行期間確實只建立了一個對象,即在堆上建立了"abc"對象。而為什麼大家都在說是2個對象呢,這裡面要澄清一個概念 該 段代碼執行過程和類的載入過程是有區別的。在類載入的過程中,確實在運行時常量池中建立了一個"abc"對象,而在代碼執行過程中確實只建立了一個String對象。
因此,這個問題如果換成 String str = new String("abc")涉及到幾個String對象?合理的解釋是2個。
5.下面這段代碼1)和2)的區別是什嗎?
public static void main(String[] args){ String str1 = "I"; //str1 += "love"+"java"; 1) str1 = str1+"love"+"java"; //2)}
1)的效率比2)的效率要高,1)中的"love"+"java"在編譯期間會被最佳化成"lovejava",而2)中的不會被最佳化。
6. String str="hello world"和String str=new String("hello world")的區別:
String str = "hello world";在編譯期間產生了字面常量和符號引用,運行期間字面常量"hello world"被儲存在運行時常量池。通過這種方式來將String對象跟引用綁定的話,JVM執行引擎會先在運行時常量池尋找是否存在相同的字面常量,如果存在,則直接將引用指向已經存在的字面常量;否則在運行時常量池開闢一個空間來儲存該字面常量,並將引用指向該字面常量。通過new關鍵字來產生對象是在堆區進行的,而在堆區進行對象產生的過程是不會去檢測該對象是否已經存在的。因此通過new來建立對象,即使內容一樣,建立出的一定是不同的對象,即使字串的內容是相同的。
(摘自http://www.cnblogs.com/dolphin0520/p/3778589.html)
Java學習(二):String、StringBuffer和StringBuilder