为什么说String是不可变的

1.什么是不可变?

简单的例子:
String s1= “abc”;
String s1=s1;
s1= “def”;
此时s1变化了吗?变了!s1的地址从指向 “abc”变成指向 “def”;
重要的不在这里,内存上的“abc”本身并没有被改变!指向 “abc”的s2也没有被改变

2.怎么做到的?

两个final ,一个在String的类修饰符,一个是String内部保存数据的数组value的变量修饰符
public final class String
private final char value[];

String类是用final关键字修饰,这说明String不可继承。

实质上用以保存内容的属性value 的定义 final char[],final修饰的字段创建以后就不可改变,这里指的是引用的地址将不可以再变

但是现在来看问题并没有解决,String本身依旧是可变的,虽然引用地址不再能变化,但是数组本身的内容还是可以变化的

也就是说Array变量只是stack上的一个引用,数据的本体结构在heap堆。String类里的value用final修饰,只是说stack里的这个叫value的引用地址不可变。没有说堆里array本身数据不可变。看这个这个例子

所以看来,String 不可变并不是因为两个final

为什么要这么做?

简单来说这是作为字面量的个人修养
回看第一部分,s2并没有被改变,这正是作为字面量的意义的体现!
没有这个特性,任何语言的基础都将不复存在,因为你无法保证你存的内容是不会被其他线程或者其他的不想管的操作所影响。
另外,考虑到字符串池本身存在的意义正式让大量存在大量使用的字符串不会被重复的创建销毁,因为在系统级别看来,这种对性能的损耗是不可接受的

结论

String的不可变还是要结合堆来看,他的不可变是字符串池里的对象不可变,而不是我们创建的String不可变

eg:补充一下
还有一些问题是相关的
比如String s1=new String(“abc”);这个过程创建了几个对象?
之前没有创建过,则创建两个对象 一个在堆 一个在PermGen常量池

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值