用以下幾種情況的代碼及分析大致講解 String s = "abc" 和 String s = new String("abc") 的區(qū)別赵颅。
情況1:
(1)
String str1 = "abc";
System.out.println(str1 == "abc");
步驟:
- 棧中開(kāi)辟一塊空間存放引用str1;
- String池中開(kāi)辟一塊空間,存放String常量"abc"猛遍;
- 引用str1指向池中String常量"abc"谷誓;
- str1所指代的地址即常量"abc"所在地址掸绞,輸出為true淹遵;
情況2:
(2)
String str2 = new String("abc");
System.out.println(str2 == "abc");
步驟:
- 棧中開(kāi)辟一塊空間存放引用str2;
- 堆中開(kāi)辟一塊空間存放一個(gè)新建的String對(duì)象"abc"遂跟;
- 引用str2指向堆中的新建的String對(duì)象"abc"逃沿;
- str2所指代的對(duì)象地址為堆中地址,而常量"abc"地址在池中漩勤,輸出為false感挥;
注意:對(duì)于通過(guò) new 產(chǎn)生的對(duì)象,會(huì)先去常量池檢查有沒(méi)有 “abc”越败,如果沒(méi)有触幼,先在常量池創(chuàng)建一個(gè) “abc” 對(duì)象,然后在堆中創(chuàng)建一個(gè)常量池中此 “abc” 對(duì)象的拷貝對(duì)象究飞。
有道面試題: String s = new String(“xyz”); 產(chǎn)生幾個(gè)對(duì)象置谦?
一個(gè)或兩個(gè)。如果常量池中原來(lái)沒(méi)有 ”xyz”, 就是兩個(gè)亿傅。如果原來(lái)的常量池中存在“xyz”時(shí)媒峡,就是一個(gè)。
對(duì)于基礎(chǔ)類型的變量和常量:變量和引用存儲(chǔ)在棧中葵擎,常量存儲(chǔ)在常量池中谅阿。
情況3、4:
(3)
String str1 = "a"酬滤;
String str2 = "b"签餐;
String str3 = str1 + "b";
//str1 和 str2 是字符串常量盯串,所以在編譯期就確定了氯檐。
//str3 中有個(gè) str1 是引用,所以不會(huì)在編譯期確定体捏。
//又因?yàn)镾tring是 final 類型的冠摄,所以在 str1 + "b" 的時(shí)候?qū)嶋H上是創(chuàng)建了一個(gè)新的對(duì)象,在把新對(duì)象的引用傳給str3几缭。
(4)
final String str1 = "a"河泳;
String str2 = "b";
String str3 = str1 + "b"奏司;
//這里和(3)的不同就是給 str1 加上了一個(gè)final乔询,這樣str1就變成了一個(gè)常量。
//這樣 str3 就可以在編譯期中就確定了
情況5:
intern()方法:當(dāng)調(diào)用 intern 方法時(shí)韵洋,如果常量池已經(jīng)包含一個(gè)等于此 String 對(duì)象的字符串(該對(duì)象由 equals(Object) 方法確定)竿刁,則返回常量池中的字符串。否則搪缨,將此 String 對(duì)象添加到池中食拜,并且返回此 String 對(duì)象的引用。
(5)
String str1 = "ab"副编;
String str2 = new String("ab");
System.out.println(str1== str2);//false
System.out.println(str2.intern() == str1);//true
System.out.println(str1== str2);//false
str2 = str2.intern();
System.out.println(str1== str2);//true
講解:
str1 指向的是常量池對(duì)象 "ab"负甸;
str2 指向的是堆中的對(duì)象 "ab";
調(diào)用了 str2 = str2.intern() 后痹届,str2.intern()判斷常量池中是否有 "ab"對(duì)象呻待,如果有就返回,沒(méi)有就創(chuàng)建并返回队腐,此時(shí)就返回的 str1 所指向的那個(gè)對(duì)象 "ab" 蚕捉。
所以 str1 == str2;
參考文章
http://www.cnblogs.com/wanlipeng/archive/2010/10/21/1857513.html
http://blog.csdn.net/lubiaopan/article/details/4776000/
http://blog.csdn.net/u014082714/article/details/50087563