为什么把String字符串转换成字符数组效率更快
一.String类
-
String类是通过private final char[] value存储字符的,具有不可变性,只提供读写方法如charAt,但是像修改操作substring()都会创造一个新的String对象,会增加内存分配垃圾回收开销
-
private保证了无法通过外部修改String的值,并且内部也没有提供修改的方法,所以确保了不可变性,每次修改只能创建新的String对象
-
final字段
- final确保String的引用无法更改,但是本身value内的值是可以更改的,就好比一个房间的门牌号不可以更改,但是可以更改房间里面的物品,这样也确保了不会因为他的引用地址改变而影响他的不可变性
- final可以防止被继承,以防在子类中有修改字符串的方法,增强不可变性
- final确保线程安全,final声明使得字符串具有可见性
//在java构造函数中会有指令重排,有可能在变量赋值之前就返回return,因为JMM(java语言定义的一套规范)只保证单线程语义优先原则,那么哪怕return在赋值之前,最后也还是能赋值,不影响单线程语义 //读取到的值还是赋值之后的值,但是涉及到多线程就有可能读取到没有赋值过的初始值,因为别的线程访问必须是在构造函数结束之后才能访问的,也就是在ret之后才能访问,访问的时候ret后面没被赋值的就还是初始值 //这导致线程安全问题,这个时候final就会强制在ret之前进行赋值操作,刷新主内存 movl $20, %y ; y=20(操作B被提前) ret ; 构造函数语义返回(此时x未赋值) movl $10, %x ; x=10(操作A被延后到return之后) - 和final相似的还有volatile,能立即刷新内存,同步所有线程,但是不能确保原子性
-
总结:字符串天然的线程安全,并且可以作为键值,因为哈希值稳定,而且能实现字符串常量池的优化
字符数组
- 数组引用存储在栈当中,指向堆内存中的数组实例,堆的数组实体中包含连续的字符存储空间,可以通过索引直接修改和访问

浙公网安备 33010602011771号