我们都知道,java中字符串都是用String, 内容和长度都是不可变的。如果想使用可变长度的,可以使用类 StringBuffer 该类的方法是安全的,可以保证线程安全
使用的过程中学到了capacity的用法,看解释是返回当前的容量。我们来试试这个方法,看看返回
package WorkStudy;
public class Tomorrow {
public static void main(String[] args) {
//返回当前的容量 StringBuffer sb1 = new StringBuffer(); //StringBuffer初始没有字符 System.out.println(sb1.capacity());
}
}
首先,我们看下StringBuffer如果为空,capacity返回什么
运行后,返回为 16
很奇怪,为什么为空返回16呢,按理说应该返回0吧
别着急,我们看看capacity的返回
@Overridepublic synchronized int capacity() {
return value.length;}
返回的是 value.length 和直接返回length是不一样的
我们来看看如果为空,返回的length是多少
在刚才程序的基础上加上
System.out.println(sb1.length());
看下返回值,返回 0
看看length的类解释
@Overridepublic synchronized int length() {
return count;}
我们来看看StringBuffer的源码
StringBuffer构造函数:
/** * Constructs a string buffer with no characters in it and an * initial capacity of 16 characters. */public StringBuffer() {
super(16); }
StringBUffer实现的AbstractStringBuilder接口的构造函数:
AbstractStringBuilder(int capacity) {
value = new char[capacity]; }
那为什么什么都不传入是16呢
我们来看看带参构造函数:
public StringBuffer(String str) {
super(str.length() + 16);
append(str);
}
原来他会把传入的字符串再加16 而length就是长度而已
如果我们传入参数后,会怎么样呢
我们先传3个String字符试试
StringBuffer sb2 = new StringBuffer("123");System.out.println(sb2.capacity());System.out.println(sb2.length());
返回为
19
3
这里发生变化了,长度为3我们都能理解,因为输入了一个长度为3的字符串
但是这个19怎么理解呢?
原来 19 = 16 + 3 说明如果有入参,返回的容量等于16 + sb2的长度(3) = 19
如果我们使用.append来给StringBuffer添加内容呢?
StringBuffer sb3 = new StringBuffer();sb3.append("123");System.out.println(sb3.capacity());System.out.println(sb3.length());
返回值为:
16
3
这又是为什么呢?不是应该是19吗?
当设置StringBuffer的容量
小于当前容量时,容量不变。 比如 3 < 16
本例中,容量依然为16。
如果大于当前容量,并且小于(当前容量+1)*2,则容量变为(当前容量+1)*2。
例如
StringBuffer sb4 = new StringBuffer();sb4.append("12345678901234567");System.out.println(sb4.capacity());System.out.println(sb4.length());
返回值为
34
17
如果大于当前容量,并且大于(当前容量+1)*2,则容量变为用户所设置的容量
如下
StringBuffer sb5 = new StringBuffer();sb5.ensureCapacity(80);System.out.println(sb5.capacity());System.out.println(sb5.length());
用户设置容量为80 > (16 + 1) * 2
如果入参有值,append或者使用ensureCapacity设置了容量,值又为甚么呢?
小伙伴可以自己试下
总结
StringBuffer实际通过一个char[]引用来保存字符串的,它的长度是固定的。
如果append的值超过了数组容量,将会执行一个扩容方法,生成一个新数组,并将旧数组的值copy进去并替代