关于String、StringBuffer、StringBuilder

【Java源码学习】关于String、StringBuffer、StringBuilder

    博客分类: 
  • Java源码学习

    说来惭愧,用Java开发这么久了都没有好好研究下Java的源代码,很多东西知其然却不知其所以然,导致现在对Java还是一知半解。趁这段时间慢慢研究下Java的源码,巩固下基础知识。 

    闲话不多说,先来看一下最常见的String、StringBuffer、StringBuilder这三个类的实现吧。为什么说String是不可变的,而StringBuffer、StringBuilder却是可变的。 

    首先这三个类是用char[] value来存储值的,而String类只能在构造函数中设置value长度和值。也就是说如果要改变String的值必须要新创建一个对象,这样在我们进行大量的字符串操作的时候就会产生大量的String对象,即使很多String对象的值都是相等的。为了解决这个问题Java引入了字符串缓存池的概念。就是将创建的String对象都放到缓存池中,如果String对象的值相等的话就使用缓存池中的对象,不再重新创建。这样就能解答诸如:
Java代码   收藏代码
  1. String a = new String("abc");  
  2. String b = new String("abc");  
到底创建了几个对象。 

    鉴于String类在大量字符串操作时产生大量对象的情况,Java又提供了两个类来解决这个问题,就是StringBuffer、StringBuilder,这两个类都继承自AbstractStringBuilder。先来看StringBuffer类的构造函数: 
Java代码   收藏代码
  1.    public StringBuffer() {  
  2. super(16);  
  3.    }  
  4.   
  5.    public StringBuffer(String str) {  
  6. super(str.length() + 16);  
  7. append(str);  
  8.    }  

父类中的构造函数 
Java代码   收藏代码
  1. AbstractStringBuilder(int capacity) {  
  2.     value = new char[capacity];  
  3. }  

StringBuffer的默认大小是16,也是使用char[]来保存值,与String类不同的是它还提供了append方法来改变value的大小和值。当value的长度不够存储是,会自动进行扩容,默认新的长度为(value.length + 1) * 2,如果仍然长度不够则扩容为新字符串的长度。 
Java代码   收藏代码
  1. public synchronized StringBuffer append(String str) {  
  2. er.append(str);  
  3.     return this;  
  4. }  

Java代码   收藏代码
  1.    public AbstractStringBuilder append(String str) {  
  2. if (str == null) str = "null";  
  3.        int len = str.length();  
  4. if (len == 0return this;  
  5. int newCount = count + len;  
  6. if (newCount > value.length)  
  7.     expandCapacity(newCount);  
  8. str.getChars(0, len, value, count);  
  9. count = newCount;  
  10. return this;  
  11.    }  
  12.   
  13.    void expandCapacity(int minimumCapacity) {  
  14. int newCapacity = (value.length + 1) * 2;  
  15.        if (newCapacity < 0) {  
  16.            newCapacity = Integer.MAX_VALUE;  
  17.        } else if (minimumCapacity > newCapacity) {  
  18.     newCapacity = minimumCapacity;  
  19. }  
  20.        value = Arrays.copyOf(value, newCapacity);  
  21.    }  


    StringBuilder提供了兼容StringBuffer的功能,那么StringBuffer与StringBuilder有什么区别呢?还是看代码: 
StringBuffer类 
Java代码   收藏代码
  1. public synchronized StringBuffer append(String str) {  
  2. er.append(str);  
  3.     return this;  
  4. }  


StringBuilder类 
Java代码   收藏代码
  1. public StringBuilder append(String str) {  
  2. er.append(str);  
  3.     return this;  
  4. }  

很容易看出StringBuffer是保证同步的,而StringBuilder不是,因此StringBuilder的效率要高一些。所以一般推荐使用StringBuilder,但是涉及到多线程调用的需要使用StringBuffer。

你可能感兴趣的:(String,StringBuilder,StringBuffer)