1. 字元串常量池(Literal Pool)
Java使用一個字元串常量池來統一儲存字元串的字面值,這樣可以複用,節省記憶體。
字元串字字面值是一個由雙引号括起來的字元序列。它是指向一個String執行個體的引用。
比如 String s = “abc”。對于“abc”,它首先是一個String literal,它在建立之後,立即利用String的intern方法,裝入到了字元串常量池并傳回這個String 執行個體的引用給s。當你再次寫abc”的時候,intern方法會先檢視是否已有這個literal了,就會直接傳回這個literal對應的String執行個體的引用。也就是說你循環1000變,記憶體裡面也隻有這麼一個String literal以及他對應的String的執行個體。
2. 編譯時計算和運作時計算的差別
String s1 = "abc";
String s2 = "abc";
String s3 = s1 + s2; // 運作時确定s3的值
String s4 = "abc" + "abc"; // 編譯時在常量池會生成字元串字面值“abcabc”
String s5 = "ab" + "cabc"; // 編譯時直接複用常量池中的字元串字面值“abcabc”
System.out.println(s3 == s4); // 傳回false
System.out.println(s4 == s5); // 傳回true
3. hashCode值
Java對象統一存儲在哈希表中,使用對象時會根據hashCode值去擷取對象,如果兩個不同對象的hashcode相同,會在哈希表中發生沖突,
哈希表中會通過連結清單來存儲這兩個不同對象。
Java對象的hashCode值是根據Java對象的記憶體位址計算出相應的方法,函數hashCode是父類Object的方法,
調用的是native方法。
a、如果兩個對象相同(及a==b),那麼它們的hashCode值一定要相同;
b、如果兩個對象的hashCode相同,它們并不一定相同;
4. String的equals()方法
String類的equals()方法,覆寫了Object類的equals()方法,判斷目前字元串與傳進來的字元串的内容是否一緻。
是以字元串相等的判斷是用equals()方法,而不是使用==。
String中的equals()方法源代碼如下:
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String)anObject;
int n = count;
if (n == anotherString.count) {
char v1[] = value;
char v2[] = anotherString.value;
int i = offset;
int j = anotherString.offset;
while (n-- != 0) {
if (v1[i++] != v2[j++])
return false;
}
return true;
}
}
return false;
}
Object對象quals()方法源代碼
public boolean equals(Object o) {
return this == o;//比較兩個對象是否相等
}
5. String 類為什麼是final
a. 字元串常量池(String pool, String intern pool, String保留池) 是Java堆記憶體中一個特殊的存儲區域, 當建立一個String對象時,假如此字元串值已經存在于常量池中,則不會建立一個新的對象,而是引用已經存在的對象。
如下面的代碼所示,将會在堆記憶體中隻建立一個實際String對象.
String s1 = "abcd";
String s2 = "abcd”;
假若字元串對象允許改變,那麼将會導緻各種邏輯錯誤,比如改變一個對象會影響到另一個獨立對象. 嚴格來說,這種常量池的思想,是一種優化手段.
b. 允許String對象緩存HashCode
Java中String對象的哈希碼被頻繁地使用, 比如在hashMap 等容器中。
字元串不變性保證了hash碼的唯一性,是以可以放心地進行緩存.這也是一種性能優化手段,意味着不必每次都去計算新的哈希碼.
c. 安全性
String被許多的Java類(庫)用來當做參數,例如 網絡連接配接位址URL,檔案路徑path,還有反射機制所需要的String參數等, 假若String不是固定不變的,将會引起各種安全隐患。
參考文檔
http://www.programcreek.com/2013/04/why-string-is-immutable-in-java/