天天看點

Java - String、StringBuilder、StringBuffer

String、StringBuilder、StringBuffer 使用場景

當字元串相加操作或者改動較少的情況下,建議使用 String str="hello"這種形式;

當字元串相加操作較多的情況下,建議使用StringBuilder,如果采用了多線程,則使用StringBuffer。

編譯期間優化字元串相加操作

"I"+"love"+"java"; 的字元串相加,在編譯期間便被優化成了"Ilovejava"

String str = "hello"+ "world"的效率就比 StringBuilder st  = new StringBuilder().append("hello").append("world")要高

String 如何存儲在記憶體?

在java中,記憶體分成兩個區域stack 和 heap , stack 用于運作(包括變量引用和邏輯運作),heap 用于存儲變量實體。

java中對String對象特殊對待,是以在heap區域分成了兩塊:

1. 一塊是String constant pool,用于存儲java字元串常量對象

2. 另一塊用于存儲普通對象及字元串對象

面試題(轉自:cnblog 海子):

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.下面這段代碼輸出結果為:

public class Main {
    public static void main(String[] args) {
        String a = "hello2";
        final String b = getHello();
        String c = b + 2;
        System.out.println((a == c));
    }
     
    public static String getHello() {
        return "hello";
    }
}      

輸出結果為false。

這裡面雖然将b用final修飾了,但是由于其指派是通過方法調用傳回的,那麼它的值隻能在運作期間确定,是以a和c指向的不是同一個對象。

5. String str = new String("abc")建立了多少個對象?

而這道題目讓人混淆的地方就是這裡,這段代碼在運作期間确實隻建立了一個對象,即在堆上建立了"abc"對象。而為什麼大家都在說是2個對象呢,這裡面要澄清一個概念  該段代碼執行過程和類的加載過程是有差別的。在類加載的過程中,确實在運作時常量池中建立了一個"abc"對象,而在代碼執行過程中确實隻建立了一個String對象。

是以,這個問題如果換成 String str = new String("abc")涉及到幾個String對象?合理的解釋是2個。

個人覺得在面試的時候如果遇到這個問題,可以向面試官詢問清楚”是這段代碼執行過程中建立了多少個對象還是涉及到多少個對象“再根據具體的來進行回答。

6. 下面這段代碼1)和2)的差別是什麼?

public class Main {
    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)中的不會被優化