浅析String、StringBuilder、StringBuffer
谈谈我对 String、StringBuilder、StringBuffer 的理解
StringBuilder、StringBuffer 和 String 一样,都是用于存储字符串的。
1、那既然有了 String ,为什么还需要他们两个呢?
原因是 String 是不可变的,它每次的字符串拼接,实际上都会 new 一个新的 String 进行接收。
2、谈谈StringBuilder、StringBuffer他们两个的联系:
我们可以知道 StringBuffer 在 1.0 的时候就发布了,那为什么还需要 StringBuilder 呢?原因是它的大部分方法都上了锁,是线程安全的,导致了效率较低!而我们有时候不需要考虑线程安全问题,追求效率!所以 StringBuilder 在 1.5 的时候就出来了!
3、StringBuilder、StringBuffer 的异同:*
不同:
- StringBuffer 它因为追求安全,给大量方法上锁,线程安全!
- StringBuilder 它因为追求效率,没有给方法上锁,线程不安全!
相同:内部方法和 StringBuffer 完全一致,因为都继承了 AbstractStringBuilder,底层数组都是用父类的。
4、源码浅析 String:

结论:final 修饰了底层的字符数组,故内容不可变。
5、源码浅析 StringBuilder:构造方法
观察构造方法:
public StringBuilder() {
super(16);
}
public StringBuilder(int capacity) {
super(capacity);
}
public StringBuilder(String str) {
super(str.length() + 16);
append(str);
}
public StringBuilder(CharSequence seq) {
this(seq.length() + 16);
append(seq);
}
结论:可以看出,它有一个默认的长度 16!而当传入参数是一个字符或者字符串时,它也会自动的传入参数的长度上加上 16!
6、源码浅析 StringBuilder:append 方法
@Override
public StringBuilder append(Object obj) {
return append(String.valueOf(obj));
}
@Override
public StringBuilder append(String str) {
super.append(str);
return this;
}
我们发现,它还是调用的父类的 append 方法,说明这个方法他并没有重写,那么 StringBuffer 也一样!
public AbstractStringBuilder append(String str) {
if (str == null)
return appendNull();
int len = str.length();
ensureCapacityInternal(count + len);
str.getChars(0, len, value, count);
count += len;
return this;
}
结论:我们可以看出,他也是可以拼接 null 的!
private AbstractStringBuilder appendNull() {
int c = count;
ensureCapacityInternal(c + 4);
final char[] value = this.value;
value[c++] = 'n';
value[c++] = 'u';
value[c++] = 'l';
value[c++] = 'l';
count = c;
return this;
}
然后观察,它接着进行了一个数组容量的判断,而数组的扩容,其实就是在里面实现的,我们点进去看一下!
private void ensureCapacityInternal(int minimumCapacity) {
// overflow-conscious code
if (minimumCapacity - value.length > 0) {
value = Arrays.copyOf(value,
newCapacity(minimumCapacity));
}
}
结论:它先是判断,当前数组容量+拼接字符 是否大于 数组长度,如果大于,则进行数组拷贝,并将底层数组的引用指向新数组!
private int newCapacity(int minCapacity) {
// overflow-conscious code
int newCapacity = (value.length << 1) + 2;
if (newCapacity - minCapacity < 0) {
newCapacity = minCapacity;
}
return (newCapacity <= 0 || MAX_ARRAY_SIZE - newCapacity < 0)
? hugeCapacity(minCapacity)
: newCapacity;
}
结论:由此可见,新数组长度扩容为原数组的 2倍+2 !
问题:那它究竟是怎么拼接字符串的呢?
sb.getChars(0, len, value, count);
进去看一下:String 的 getChars 方法
public void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin)
{
if (srcBegin < 0)
throw new StringIndexOutOfBoundsException(srcBegin);
if ((srcEnd < 0) || (srcEnd > count))
throw new StringIndexOutOfBoundsException(srcEnd);
if (srcBegin > srcEnd)
throw new StringIndexOutOfBoundsException("srcBegin > srcEnd");
System.arraycopy(value, srcBegin, dst, dstBegin, srcEnd - srcBegin);
}
实际调用了一个系统类方法:arraycopy,再点进去看一下!
public static native void arraycopy(Object src, int srcPos,
Object dest, int destPos,
int length);
结论:底层最终是调用的本地方法,实现了的字符数组拷贝,但由于本地方法是可以和操作系统直接打交道的,所以它的 append 字符串拼接效率会高于 String!
浅析String、StringBuilder、StringBuffer的更多相关文章
- 深入源码剖析String,StringBuilder,StringBuffer
[String,StringBuffer,StringBulider] 深入源码剖析String,StringBuilder,StringBuffer [作者:高瑞林] [博客地址]http://ww ...
- String, StringBuilder, StringBuffer问题
1. 区别 String为字符串常量,而StringBuilder和StringBuffer都是字符串变量,其中StringBuilder线程非安全,StringBuffer线程安全. 每次对 Str ...
- String StringBuilder StringBuffer区别
String StringBuilder StringBuffer String类是final类,不可以被继承,且它的成员方法也是final方法,当一个字符串对象进行操作操作时,任何的改变不会影响到这 ...
- difference among String,StringBuilder,StringBuffer
difference among String,StringBuilder,StringBuffer String常用构造函数 String(byte[] bytes) String(byte[] b ...
- JDK源码分析系列---String,StringBuilder,StringBuffer
JDK源码分析系列---String,StringBuilder,StringBuffer 1.String public final class String implements java.io. ...
- java中String StringBuilder StringBuffer比较和效率(性能)测试
string stringbuilder stringbuffer三者的区别 从JDK源码看,String.StringBuilder.StringBuffer都是存放在char[] 数组字符串. 简 ...
- 浅析String、StringBuffer、StringBuilder的区别以及性能区别
前奏: 比较三者之间的区别在与区别他们做相同的事情的时候的区别,那就是在我们常见的拼接字符串的时候,StringBuffer.StringBuilder调用的是appende()方法,而String很 ...
- string,stringbuilder,stringbuffer用法
总结:1.如果要操作少量的数据用 = String ==================================>字符串常量2.单线程操作字符串缓冲区 下操作大量数据 = Strin ...
- java中string stringbuilder stringbuffer 的区别
1. String 类 String的值是不可变的,这就导致每次对String的操作都会生成新的String对象,不仅效率低下,而且大量浪费有限的内存空间. String a = "a&qu ...
- String,StringBuilder,StringBuffer
(转:http://blog.csdn.net/rmn190/article/details/1492013) String 字符串常量StringBuffer 字符串变量(线程安全)String ...
随机推荐
- java并发Exchanger的使用
目录 简介 类定义 类继承 构造函数 两个主要方法 具体的例子 结语 简介 Exchanger是java 5引入的并发类,Exchanger顾名思义就是用来做交换的.这里主要是两个线程之间交换持有的对 ...
- centos7安装及部署zabbix监控
一:实验环境 server.zabbix.com-------------------- 192.168.200.11 agent.zabbix.com------------------------ ...
- Java多线程并发系列之闭锁(Latch)和栅栏(CyclicBarrier)
JAVA并发包中有三个类用于同步一批线程的行为,分别是闭锁(Latch),信号灯(Semaphore)和栅栏(CyclicBarrier).本贴主要说明闭锁(Latch)和栅栏(CyclicBarri ...
- 回顾2016年最火热的IT技术 科技发展让人惊叹!
编者按: 科技的发展速度总是让人们惊诧,仅从2016年来看,不仅有新涌现出来的技术和概念,还有很多甚至十年前出现的技术在今年呈现爆发性扩张.在这篇文章中,笔者将2016年最火热的IT技术尽收囊中,与各 ...
- Java Web:jstl处理字符串
用法:${fn:methodName(args....)} 在使用这些函数之前必须在JSP中引入标准函数的声明<%@ taglib prefix="fn" uri=" ...
- 深度解析国内首个云原生数据库POLARDB的“王者荣耀”
随着移动互联网.电子商务的高速发展,被使用最多的企业级开源数据系统MySQL面临着巨大挑战--为迎接"双11"的高并发要提前做好分库分表;用户不断激增要将读写分离才能应对每天上亿次 ...
- 关于fastjson在序列化成JSON串时字段增加的问题
今天在项目中遇到控制器中返回的对象经过fastjsonMessageConverter转换后,前台收到的json中多了一个字段A的问题.而返回的这个对象中根本就没有定义这个字段A. 查了好久才发现对象 ...
- 你所不知道的Python | 字符串连接的秘密
字符串连接,就是将2个或以上的字符串合并成一个,看上去连接字符串是一个非常基础的小问题,但是在Python中,我们可以用多种方式实现字符串的连接,稍有不慎就有可能因为选择不当而给程序带来性能损失. 方 ...
- MySQL数据库的套接字文件和pid文件
MySQL数据库的套接字文件和pid文件 socket文件:当用Unix域套接字方式进行连接时需要的文件. pid文件:MySQL实例的进程ID文件. MySQL表结构文件:用来存放MySQL表结构定 ...
- nodeJS生成xlsx以及设置样式
参考: https://www.npmjs.com/package/xlsx-style https://www.jianshu.com/p/877631e7e411 https://sheetjs. ...