String数据类型是引用类型,但是也是比较特殊的引用类型,他有两个特别之处。
一个是当给String类型数据赋值后,它开辟的内存里面的数值就不能再发生改变了(如果想再次改变该String类型变量值,就需要再新开辟一段内存,并用该句柄指向新内存地址)。
第二个是String类型数据是共享式数据,因此当用直接值赋值法给两个String类型数据赋值时,如果当赋的“值”相等,则默认为两个String类型数据的句柄指向了同一块堆内存,地址是相同的(其他引用类型数据没有这个特性,值相同却地址不同),因此这两个数据数值相同,地址也相同。
如果两个String类型数据一个是直接值赋值的,则句柄指向新开辟出来的内存地址;另一个是new出来的,则第二个数据的内存分配情况是先匿名对象开辟出来一块堆内存,然后在new出来一块堆内存,而句柄指向了后一块内存地址。因此这两个数据地址是不相同的,只是数值相等。
下面看个小例子:
String s1 ="abc";
String s2 ="abc";
String s3 =new String("abc");
if(s1==s2){
System.out.println("这两个数据地址相同");
}
else{
System.out.println("这两个数据地址不相同");
}
if(s1==s3){
System.out.println("这两个数据地址相同");
}
else{
System.out.println("这两个数据地址不相同");
}
输出结果是:
这是为什么呢?我们看看内存空间的指向。
当s1和s2相比时:
当s1和s3相比时:
所以s1和s2的地址是相同的,s1和s3的地址是不同的。