
本文共 1003 字,大约阅读时间需要 3 分钟。
1.String与StringBuffer、StringBuilder的比较
String在字符串常量池中是不可变的对象
StringBuffer与StringBulder是可变的
例如:
String a = "ab"; a="abc";
第一句首先是在字符串常量池中开辟了一块空间用于存放"a";
当改变a的值后,会在字符串常量池中开辟一块新空间存放"abc";
等同于生成了一个新的 String 对象,然后将指针指向新的 String 对象
而采用new String()是在常量池外的堆内存上开辟空间,和其他引用类型存储方式一样
这样的方式效率低下,所以对于经常改变的字符串,最好不要使用String
因为 String 底层是用数组来存值的,数组长度一旦创建就不可修改,所以导致上述问题。
StringBuffer 和StringBuilder可以解决 String 频繁修改造成的空间资源浪费的问题。
但StringBuffer和StringBuilder 底层也是使用数组来存值。
2.StringBuffer与StringBuilder
StringBuffer和StringBuilder类似,唯一不同是StringBuffer在许多方法前添加了synchronized关键字,也就是给这个方法添加了一个锁,用来保证线程安全
StringBuffer 线程安全 效率略低
StringBuilder 线程不安全 效率最高
3.StringBuffer的扩容方式
StringBuffer 数组的默认长度为 16
使用无参构造函数来创建对象
StringBuffer str = new StringBuffer();
使用有参构造创建对象,数组长度=值的长度+16
使用有参构造函数来创建对象
StringBuffer str = new StringBuffer("abc");
注意:str.length() 方法返回的并不是底层数组的长度,而是它的有效长度(值的长度)。
StringBuffer 一旦创建,默认会有 16 个字节的空间去修改,但是一旦追加的字符串长度超过 16,如何处理?
StringBuffer 不会重新开辟一块新的内存区域,而是在原有的基础上进行扩容,通过调用父类 ensureCapacityInternal() 方法对底层数组进行扩容,保持引用不变。
发表评论
最新留言
关于作者
