轉(zhuǎn)自//blog.csdn.net/chen364567628/article/details/52614827
為了清晰了解String類萍悴,本人做了如下測試:
String a = "c";
String b = "c";
System.out.println(a == b);//true
說明指向同一塊內(nèi)存空間
System.out.println(a.equals(b));//true
String c = "e";
String d = "e";
String s = a + c;
String ss = b + d;
System.out.println(s == ss);//false
變量相加開辟了新空間
System.out.println(s.equals(ss));//true
String sss = "ce";
String ssss = new String("ce");
System.out.println(ss == sss);//false
在不同的內(nèi)存區(qū)域
System.out.println(ss == ssss);//false
new出來的在【堆】中
System.out.println(ss.equals(sss));//true
System.out.println(ss.equals(ssss));//true
結(jié)論:String相加后的變量在堆中,""在常量池中寓免。
String x = "m" + "n";
String y = "m" + "n";
String xx = "mn";
System.out.println(x==xx);//true
System.out.println(x.equals(xx));//true
System.out.println(x==y);//true
說明:""這種相加不在堆中開辟空間癣诱,直接在常量池中添加。
System.out.println(x.equals(y));//true
String z = a+b+c+d;
String zz = "c"+"c"+"e"+"e";
System.out.println(z==zz);//false 說明:與上述結(jié)論不矛盾
System.out.println(z.equals(zz));//true
StringBuilder sb = new StringBuilder();
StringBuilder sb1 = new StringBuilder();
sb.append("c").append("c").append("e").append("e");
sb1.append(a).append(b).append(c).append(d);
String t = sb.toString(); //堆中
String t1 = sb1.toString();
String tt = "ccee";
System.out.println("---------------------------------");
System.out.println(t1==t);//false
字符串常量的追加和字符串變量的追加不在同一塊內(nèi)存
System.out.println(t1.equals(t));//true
System.out.println(tt==t);//false
字符追加后不在常量池中袜香,應該在堆中
System.out.println(tt.equals(t));//true
String ttt = new String("ccee");
String tttt = new String("ccee");
System.out.println(ttt==tttt);//false
堆中不檢查重復
System.out.println(ttt.equals(tttt));//true
System.out.println(t==ttt);//false
結(jié)論:堆中不檢查數(shù)據(jù)是否重復撕予,與實際不矛盾
System.out.println(t.equals(ttt));//true
System.out.println(z==t);//false
System.out.println(zz==t);//false
System.out.println(z.equals(t));//true
System.out.println(zz.equals(t));//true
String r = new String("c");
System.out.println(r==a);//false
System.out.println(r.equals(a));//true
String q = new String(sb);
System.out.println(q==z);//false
System.out.println(q.equals(z));//true
System.out.println(q==zz);//false
System.out.println(q.equals(zz));//true
//總結(jié):String a = "c";String x = "m" + "n";在常量池中。
//String ssss = new String("ce");String s = a + c;在堆中蜈首。
//堆特點:不檢查重復实抡。 常量池特點:檢查重復,共享數(shù)據(jù)欢策。 棧特點:共享(檢查)吆寨,先進后出。
測試結(jié)論:沒new的字符串在常量池中踩寇,new出來的在堆內(nèi)存中啄清,字符串直接相加在常量池中,String類型變量相加在堆內(nèi)存中姑荷。
測試結(jié)果:
那么關于如下問題就很明顯了:
(1)
String s="a"+"b"+"c"+"d"
創(chuàng)建了幾個對象(假設之前串池是空的)答案是:1個
解釋:這個問題涉及到了字符串常量池和字符串拼接
String a="a"+"b"+"c"
通過編譯器優(yōu)化后盒延,得到的效果是
String a="abc"
此時缩擂,如果字符串常量池中存在abc,則該語句并不會創(chuàng)建對象添寺,只是講字符串常量池中的引用返回而已胯盯。
如果字符串常量池中不存在“abc”,則會創(chuàng)建并放入字符串常量池计露,并返回引用博脑,此時會有一個對象進行創(chuàng)建。
(2)String str = new String("abc");
創(chuàng)建了幾個對象
答案是:2個
new String()創(chuàng)建了一個對象票罐,并將其復制給引用變量str叉趣;
“abc”創(chuàng)建了一個對象,并會將其放入字符串常量池中该押。
(3)
String a = "a";
String b = "b";
String c = "c";
String d = "d";
String s = a+b+c+d;
這句話創(chuàng)建了幾個對象
答案是:3個 “ab”“abc”“abcd”
首先明確:字符串常量不產(chǎn)生對象疗杉,字符串變量相加會產(chǎn)生對象