为了清晰了解String类,java中最特殊的类,探索之路

转自//blog.csdn.net/chen364567628/article/details/52614827
为了清晰了解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类,java中最特殊的类,探索之路_第1张图片

为了清晰了解String类,java中最特殊的类,探索之路_第2张图片

为了清晰了解String类,java中最特殊的类,探索之路_第3张图片

那么关于如下问题就很明显了:
(1) String s="a"+"b"+"c"+"d"创建了几个对象(假设之前串池是空的)
答案是:1个
解释:这个问题涉及到了字符串常量池和字符串拼接 String a="a"+"b"+"c"
通过编译器优化后,得到的效果是 String a="abc"
此时,如果字符串常量池中存在abc,则该语句并不会创建对象,只是讲字符串常量池中的引用返回而已。
如果字符串常量池中不存在“abc”,则会创建并放入字符串常量池,并返回引用,此时会有一个对象进行创建。

(2)String str = new String("abc");创建了几个对象
答案是:2个
new String()创建了一个对象,并将其复制给引用变量str;
“abc”创建了一个对象,并会将其放入字符串常量池中。

(3)

String a = "a";

String b = "b";

String c = "c";

String d = "d";

String s = a+b+c+d;  

这句话创建了几个对象
答案是:3个 “ab”“abc”“abcd”

首先明确:字符串常量不产生对象,字符串变量相加会产生对象

你可能感兴趣的:(为了清晰了解String类,java中最特殊的类,探索之路)