字符串的创建机制

public class Test{
public static void main(String[] args){
String s1 = new String("amit");
System.out.println(s1.replace('m','r'));
System.out.println(s1);
String s3 = "arit";
String s4 = "arit";
String s2 = s1.replace('m','r');
System.out.println(s2);
System.out.println(s2 == s3);
System.out.println(s3 == s4);
}

}


这算是道难题,需要完全理解字符串的创建机制。

String s1 = new String("amit");    //这句在堆上创建了一个新的值为amit的字符串,用new创建是完全当做对象看待的。

System.out.println(s1.replace('m','r'));   //此句话实际上相当于相当于在堆上创建了一个值为arit的字符串对象,然后打印到控制台。但没有让任何String引用指向它,所以短命的它将在下次垃圾回收时被回收。

System.out.println(s1);          //s1依然指向着原来在堆上创建的amit字符串,所以输出amit

String s3 = "arit";         //使用双引号创建字符串与用new完全不同,他会检测在栈中的字符串存储池中是否有值为arit的字符串,如果有则指向它,如果没有,则在栈中创建它;在第一句中虽然创建了一个值为arit的字符串,但是是在堆中创建的,不可共享。所以这里在栈中新建了一个arit字符串。

String s4 = "arit";          //如上所说,在存储池中查找到一个arit字符串,即s3指向的字符串,然后指向它,此语句其实并没有创建字符串,而是和s3指向了同一个字符串。这就是传说中的字符串共享。

String s2 = s1.replace('m','r');         //由于字符串是不可变的,所以这里的s1.replace('m','r')并不是把s1修改为arit,而是在堆中创建了一个新的值为arit的字符串,注意这里是在堆中创建的,而没有在栈中的字符串存储池中寻找arit然后共享,然后让s2指向了它。

System.out.println(s2);              //输出了s1.replace('m','r');语句在堆中创建的值为arit的那个字符串。

System.out.println(s2 == s3);          //理解了前面就理解了这个,虽然s2的值与s3一样都为arit,但是却没有实现共享机制,因为s2不是用s2 = “arit”的形式创建的,s2创建在堆中,而s3是创建在了共享池中。二者指向不同的对象,所以用==比较为false。

System.out.println(s3 == s4);//因为s3和s4都是在共享池中创建的,所以s3和s4实际上指向了同一个对象,所以用==比较为true。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值