1. 程式人生 > 其它 >JDK原始碼筆記04 String

JDK原始碼筆記04 String

something before start

說實話String在我心裡一直挺神祕的,特別是之前學的時候接觸到的常量池的概念(我這會兒琢磨著不會就是一個Map吧)

感覺jvm關於String的機制比較多,所以相比於之前的會多一個說明
稍微概覽了一下,感覺很多實現都是沒必要看的,主要記一下一些機制上的東西

String類說明

以下說明來自String原始碼

  1. 所有的字串都是String類的例項。意思就是說字串常量也可以呼叫String裡的方法。
    這個規則常用的地方是字串比較的時候 "常量".equals(str) ,這樣就不用對變數是否取null進行多一次的判斷

  2. String是不可變類,建立之後就不能變化。StringBuffer可以支援變化字串

  3. Java對String物件相加,其他類轉換成String提供支援 //toString

  4. 除非特殊說明,給建構函式傳入null會丟擲異常

  5. String以UTF-16儲存,增補字元以surrogate pair的形式儲存

  6. 除非特殊說明,比較(compare)字串不考慮記憶體地址

  7. 字串拼接的實現方式由java編譯器決定,取決於JDK版本,可能會用StringBuffer、StringBuilder或StringConcatFactory的方法。
    注:字串+ 運算會建立一個物件,然後使用相應方法,所以效率會相應更差一點

  8. 字串轉換的方法通常是通過toString實現

屬性

@Stable //一個域的元件(component)頂多被修改一次,即第一個非空值,他的值被稱為穩定值(stable value)
private final byte[] value;


private final byte coder;
//有兩種取值, 後面有很多的處理是把兩種取值分開的,我猜應該是為了讓效能更好點,因為LATIN1包含的是大部分程式設計中常用的字元,而且不需要考慮增補字元的情況。
//在建構函式裡對字串的內容進行判斷來進行初始化
//LATIN1
//UTF16

//這個值由JVM注入,如果false,則字串就一直都會是以UTF16的形式被處理。一般都是true
static final boolean COMPACT_STRINGS;


/** Cache the hash code for the string */
private int hash; // Default to 0

/**
* Cache if the hash has been calculated as actually being zero, enabling
* us to avoid recalculating this.
*/
private boolean hashIsZero; // Default to false;

方法

構造方法

    String(char[] value, int off, int len, Void sig) {
        if (len == 0) {
            this.value = "".value;
            this.coder = "".coder;
            return;
        }
        if (COMPACT_STRINGS) {
        
						//如果value只包含拉丁文的字元,則返回相應byte[],否則返回null
            byte[] val = StringUTF16.compress(value, off, len);
            if (val != null) {
                this.value = val;
                this.coder = LATIN1;
                return;
            }
        }
        this.coder = UTF16;
        this.value = StringUTF16.toBytes(value, off, len);
    }

intern

這是一個底層方法,以下是他的簡單說明

  1. 字串池,初始為空,由String類進行拓展 //實際上底層是hashTable
  2. intern()被呼叫,如果池中已經有相同的string物件(通過equal函式對比),則直接返回,否則將這個物件新增到字串池中,返回指向這個物件的引用
  3. 所有的字串和字串常量都interned
public native String intern();

text-block jdk15新特性

喜極而泣

String a = """
現在
終於
可以
不用
手動拼接換行字串了!    
:D
""";
System.out.println(a);

//輸出
現在
終於
可以
不用
手動拼接換行字串了!
:D

首尾用三個引號框起來的
就是這麼簡單(響指

end

所以其實無論怎麼去new,其實value的值都是會複用的
然後底層確實是Map
String類也有一堆工具方法,其實基本上都可以見名知意,就不多贅述了。