前言
之前在学习java的String类时经常会听到String在创建后就不可修改,但是用时没太大感觉,最近又仔细看了下有了些新的理解。
一、简要分析
示例代码如下:
String s1 = "abc";
System.out.println("s1:"+s1);
s1 = "bcd";
System.out.println("s1:"+s1);
这段代码在运行后会输出
s1:abc
s1:bcd
但是这不是值已经改变了吗,没有发现String类不可变的地方,在Debug后发现第一输出的s1和第二个输出s1的地址值发生了变化
这就需要模拟下String在内存中的存储
在第一次申请时s1指向常量池中0x542这个地址
在s1=bcd后指向了0x544这个地址空间
由此可见s1在修改后会重新申请一个空间存放,s1的引用指向另一片存储空间,但是之前申请那个"abc"的空间是否被释放呢,于是又做了次测试如下所示
创建了个String 对象 s 值为abc,通过debug输出内存地址,发现地址指向了0x542,在内存中模拟指向应该是这样的
由此印证之前看到的一个结论:以 " "方式创建的字符串,只要字符串完全相同,那么jvm就只会创建一个对象并且保留在常量池中,在 下次使用 双引号 创建String对象时会先在常量池中找有没有相同的字符串,有的话将引用地址直接指向这里,这里也体现了String对象的共享性,没有就在常量池中创建一个字符串对象,然后将引用指向这里。
二、设为不变量的好处
节省空间:字符串常量在常量池中可以共享。
2.提高效率:String会被不同的线程共享,是线程安全的,在多线程中不需要同步操作。
3.安全:String通常在用户名,密码时使用,由于不可变可以避免黑客等对其进行恶意修改。