3 回答

TA貢獻(xiàn)1831條經(jīng)驗(yàn) 獲得超4個(gè)贊
一樓回答太籠統(tǒng),而且拋開JVM和JDK版本談內(nèi)存分配都是耍流氓。
以提問的為例:
String str1 = "a";
String str2 = "b";
String str3 = "ab";
這種直接定義字符串,JVM認(rèn)為字符串是不變量,也就是線程安全的,因?yàn)檫@種字符串直接分配在方法區(qū)的常量池中.
String str4 = new String("a");
String str5 = new String("b");
String str6= new String("ab");
有new關(guān)鍵字,說(shuō)明這種字符串是分配在堆上.可以使用如下方法驗(yàn)證:
public static void main(String[] args) {
String str1 = "a";
String str2 = "b";
String str3 = "ab";
String str4 = new String("a");
String str5 = new String("b");
String str6= new String("ab");
System.out.println(str1 == str4); // false,說(shuō)明str1和str4的內(nèi)存地址不一樣,一個(gè)在方法區(qū),一個(gè)在堆.
System.out.println(str1 == str4.intern()); // true,str4存入常量池后并沒有重新創(chuàng)建一塊內(nèi)存,而是使用了已有的常量句柄.
}
回答一下為什么plus1~6的hashcode一樣,是因?yàn)槟銢]有去重寫String的hashcode方法。而String默認(rèn)hashcode的實(shí)現(xiàn)為:
@Override public int hashCode() {
int hash = hashCode;
if (hash == 0) {
if (count == 0) {
return 0;
}
for (int i = 0; i < count; ++i) {
hash = 31 * hash + charAt(i);
}
hashCode = hash;
}
return hash;
}
只是對(duì)字面常量做了處理,而plus1~6的字面常量一樣,所以hashcode值當(dāng)然一致。然后hashcode一致,不代表它們?cè)趈vm分配的內(nèi)存地址一致。

TA貢獻(xiàn)1807條經(jīng)驗(yàn) 獲得超9個(gè)贊
相同字符串在內(nèi)存中只有一個(gè)實(shí)例
------------------------------分割線----------------
本答案過(guò)于籠統(tǒng),且有誤導(dǎo)之嫌,請(qǐng)大家移步正一兄的回答
添加回答
舉報(bào)