关于String,StringBuffer,和StringBuilder的一点心得


一、关于String,首先需要知道String是final的,内部实现是一个final的char[],它有两种构造方法,一种是通过new String 在JVM的堆内存进行分配。一种是通过String a = "abc"这种方式,这种JVM首先会在String pool中查找是否有“abc”,如果有则把地址给a,若没有,则创建一个,并放入到String pool中。
上面也就解释了
String a = "abc";
String b = "abc";
String c = new String("abc");
a==b为true,a==c为false.
但是有一种特殊的
String d = a+"d";//此时d的内容为abcd
String e = "abcd";
String f = "ab"+"cd";
d==e为false, e==f 为true
可以认为是这个样子的,所有用“”修饰的,都在String pool中,所以e和f相等
那么来看d和e,d通过a+“d”实际上执行了new StringBuilder().append(a).append("d").toString();它是在JVM的堆内存生成了一个对象,所以和String pool的地址不可能一样。
另外看源码,发现String中有很多final并没有给初始值,这样做是可以的,只要在构造方法中给初始值就行了。也算是突破了我的一个认知。
二。 StringBuilder非线程安全,StringBuffer是线程安全的。(StringBuffer方法通过synchronized加了同步锁)
这里说两点:
第一:关于append的实现,appen是通过传入的字符串的getChars实现的。
例如:(StringBuilder也一样,都是继承了AbstractStringBuilder,appen就是在该类中实现的。)
StringBuffer d = new StringBuffer();
d.append("a");
此处appen是通过传入的字符串"a"的 getChars(int start,int end,char c[],int offset) 方法实现的, 该方法的作用是将当前字符串从start到end-1位置上的字符复制到字符数组c中,并从c的offset处开始存放。
第二:关于扩容
每次append时都需要对当前数组进行判断,如果长度超过当前数组的长度,则对数组进行扩容。即当前数组长度的2倍再加上2(这里加2,我自己认为是为了防止初始化的时候用户传了0,即当前数组长度为0,乘以2还是0这种情况,当然默认值时16),
下面是代码:
(当然扩容时不能说就是2倍+2,如果2倍+2还是比需求的量要小的话,那就是当前的需求量。minimumCapacity即为当前的需求量。)

void expandCapacity(int minimumCapacity) {
	int newCapacity = value.length * 2 + 2;
	if (newCapacity - minimumCapacity < 0)
		newCapacity = minimumCapacity;
	if (newCapacity < 0) {
		if (minimumCapacity < 0) // overflow throw new OutOfMemoryError();
			newCapacity = Integer.MAX_VALUE;
	}
	value = Arrays.copyOf(value, newCapacity);
}






  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值