首先我们说一下 java 中 String,StringBuffer 和 StringBuilder 的相同点:
通过源码我们可以发现无论是 String,StringBuffer 还是 StringBuilder 它们的底层都是使用 char[] 数组进行存储.
接着我们说一下它们三者之间的不同点:
String: 不可变的字符序列.
StringBuffer: 可变的字符序列, 是线程安全的, 效率低.
StringBuilder: 可变的字符序列, 是线程不安全的, 效率高.
现在我们通过源码分析它们的不同点:
1. 分析 String 的源码
- /** The value is used for character storage. */
- private final char value[]; //char[] 数组被 final 修饰, 所以它是不可变的字符序列.
2. 分析 StringBuffer 的源码
- char[] value; // 在 StringBuffer 的父类中, 没有用 final 修饰, 是一个可变 char[] 数组
- public StringBuffer() {
- super(16); // 调用父类的构造器方法
- }
- // 父类的构造器
- AbstractStringBuilder(int capacity) {
- value = new char[capacity]; // 默认为我们创建了一个长度为 16 的 char[] 数组
- }
- // 截取 StringBuffer 类中的一部分代码, 我们可以发现方法前都是用 synchronized 关键字修饰的, 所以是线程安全的, 执行效率比较慢.
- @Override
- public synchronized void setCharAt(int index, char ch) {
- if ((index <0) || (index>= count))
- throw new StringIndexOutOfBoundsException(index);
- toStringCache = null;
- value[index] = ch;
- }
- @Override
- public synchronized StringBuffer append(Object obj) {
- toStringCache = null;
- super.append(String.valueOf(obj));
- return this;
- }
- @Override
- public synchronized StringBuffer append(String str) {
- toStringCache = null;
- super.append(str);
- return this;
- }
3. 分析 StringBuilder 的源码
- char[] value; // 在 StringBuilder 的父类中, 没有用 final 修饰, 是一个可变的 char[] 数组
- public StringBuilder() {
- super(16); // 调用父类的构造方法
- }
- // 父类的构造器
- AbstractStringBuilder(int capacity) {
- value = new char[capacity]; // 默认为我们创建了一个长度为 16 的 char[] 数组
- }
- // 截取 StringBuilder 类中的一部分代码, 我们可以发现方法前没有用 synchronized 关键字修饰, 所以是线程不安全的, 执行效率比较快.
- public void setCharAt(int index, char ch) {
- if ((index <0) || (index>= count))
- throw new StringIndexOutOfBoundsException(index);
- value[index] = ch;
- }
- public AbstractStringBuilder append(Object obj) {
- return append(String.valueOf(obj));
- }
注意: 你在使用 StringBuffer 或者 StringBuider 时, 如果字符串长度过大, 建议使用它们的另外一个构造器, 提前创建一个长度大的 char[] 数组, 这样可以提高效率.
通过源码分析:
- public StringBuffer(int capacity) {
- super(capacity); // 调用父类的构造器
- }
- // 父类的构造方法
- AbstractStringBuilder(int capacity) {
- value = new char[capacity]; // 根据传入的参数, 创建 char[] 数组的长度, 这样做可以提高效率.
- }
- public StringBuilder(int capacity) {
- super(capacity); // 调用父类的构造器
- }
- // 父类的构造方法
- AbstractStringBuilder(int capacity) {
- value = new char[capacity]; // 根据传入的参数, 创建 char[] 数组的长度, 这样做可以提高效率.
- }
来源: http://www.bubuko.com/infodetail-3035400.html