为了清晰了解String类,本人做了如下测试:
String a = "c";
String b = "c";
System.out.println(a == b);//true 说明指向同一块内存空间
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 在不同的内存区域
System.out.println(ss == ssss);//false new出来的在【堆】中
System.out.println(ss.equals(sss));//true
System.out.println(ss.equals(ssss));//true 结论: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 说明:与上述结论不矛盾
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 字符串常量的追加和字符串变量的追加不在同一块内存
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 结论:堆中不检查数据是否重复,与实际不矛盾
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
//总结:String a = "c";String x = "m" + "n";在常量池中。
//String ssss = new String("ce");String s = a + c;在堆中。
//堆特点:不检查重复。 常量池特点:检查重复,共享数据。 栈特点:共享(检查),先进后出。
测试结论:没new的字符串在常量池中,new出来的在堆内存中,字符串直接相加在常量池中,String类型变量相加在堆内存中。
测试结果:
那么关于如下问题就很明显了:
String s="a"+"b"+"c"+"d"创建了几个对象(假设之前串池是空的)
String str = new String("abc");创建了几个对象
String a = "a";
String b = "b";
String c = "c";
String d = "d";
String s = a+b+c+d; 这句话创建了几个对象
首先明确:字符串常量不产生对象,字符串变量相加会产生对象