StringBuffer/StringBuilder/String关键点源码分析

花了好久时间都没能正常下载到一份JDK源码,后来灵机一动上github搜了一下,发现了好多别人push上去的JDK源码。有人还给出了自己分析研究源码的记录。

在这个目录下(jdk7u-jdk/src/share/classes/java/lang),就能看到StringBuffer.java , StringBuilder.java和String.java。下面对照源码,理清及格关键问题,就能更好的理解它们。

1. 从使用/接口上,它们之间最大的区别是什么?

(1)String没有append()方法。StringBuffer/StringBuilder都有append()。
(2)进行字符串拼接时,String只能用“+”,每一次“+”都涉及到新内存的申请和旧内存的释放,这样效率较低。所以使用由扩容机制的StringBuffer/StringBuilder去做字符串拼接(append())效率会高。
(3)String用“+”做拼接,也并非效率就绝对低。比如下面的代码,用String反而效率最高

String S1 = “This is only a” + “ simple” + “ test”;

因为有JVM的优化,上面这行代码就相当于

String S1 = "This is only a simple test";

2. 它们继承关系是怎样的?

(1) String

public final class String implements java.io.Serializable, Comparable<String>, CharSequence

String没有继承任何类,只实现了CharSequence等接口。final说明该类不能被继承。

(2) StringBuilder

public final class StringBuilder extends AbstractStringBuilder implements java.io.Serializable, CharSequence

StringBuilder 继承了AbstractStringBuilder 。

(3) StringBuffer

public final class StringBuffer extends AbstractStringBuilder implements java.io.Serializable, CharSequence

StringBuffer 继承了AbstractStringBuilder 。

AbstractStringBuilder 是何方神圣

abstract class AbstractStringBuilder implements Appendable, CharSequence

AbstractStringBuilder 实现了CharSequence接口(String也实现了这个接口)。

而三者都实现了CharSequence接口,可见对于字符串处理,CharSequence的重要性。观其源码,CharSequence只是简单定义了下面几个方法,它们也就是字符串处理必须实现的最核心的方法:

  int length();
  char charAt(int index);
  CharSequence subSequence(int start, int end);
  public String toString();

3. 它们对于字符数据存储的区别?

Class The value for character storage
String private final char value[];
StringBuffer,StringBuilder char[] value = new char[capacity];

String的value是final类型,这就说明了String对象是不可变的。

4. StringBuffer/StringBuilder是如何扩容的?

以StringBuffer为例,它的构造函数是这样实现的:

    public StringBuffer() {
        super(16);
}

这里设置了初始值为16个字节。它的扩容函数如下:

    void expandCapacity(int minimumCapacity) {
        int newCapacity = value.length * 2 + 2;
       //下面的代码省略
    }

所以,capacity的容量是这样增长的: 16, 34, 70, 142, 286

5. 为何说StringBuffer是线程安全的?

借用源码来解释,StringBuffer的length()方法实现如下:

    public synchronized int length() {
        return count;
}

而StringBuilder/String是这样实现length()的:

    public int length() {
        return count;
}

StringBuffer中大量使用了synchronized关键字,synchronized可以给代码块加锁。

6 参考

  • http://ryxxlong.iteye.com/blog/607129
  • JDK源码

你可能感兴趣的:(Java,源码分析)