String StringBuilder和StringBuffer 结合源码解析

String StringBuilder和StringBuffer 结合源码解析

当我们在对字符串进行操作的时候,就会使用到String、StringBuilder和StringBuffer,然后在使用的时候我们还要注意三者的区别。

一、String
public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence {}
在String的源码中,String的类是final的,因此该类是不能被继承的,那么为什么String类型的变量是不允许改变的呢,初学经常误认为是变化了的,其实不然,事实上是final在修饰基本类型的时候,是其变量的值不可变;修饰引用对象的时候,是其引用不可变,其对象的内容可变。
例如:
String  sb = "abc";
sb = "abcd";
sb变量会存入到jvm的栈内存中,只是sb刚开始的时候,是指向的abc,后面又指向了abcd,其引用没有变化。
String s = "abc";
char data[] = {'a', 'b', 'c'};
String str = new String(data);
System.out.println(str);//abc
System.out.println(str.length());//长度为3
其实,String的内部是个数组,源码如下:
/**
 * Allocates a new {@code String} so that it represents the sequence of
 * characters currently contained in the character array argument. The
 * contents of the character array are copied; subsequent modification of
 * the character array does not affect the newly created string.
 *
 * @param  value
 *         The initial value of the string
 */
public String(char value[]) {
    this.value = Arrays.copyOf(value, value.length);
}
那么为什么String类型的变量是不可变的呢?从源码中解析:
/** The value is used for character storage. */
private final char value[];

/** Cache the hash code for the string */
private int hash; // Default to 0
这两个属性其中char是final的,也是不可变的,private类型,其中,在String中没有两个属性的get、set方法,既无法去设置String的值,因此是无法改变的。
二、StringBuilder


源码中:

public final class StringBuilder
    extends AbstractStringBuilder
    implements java.io.Serializable, CharSequence{}
你会发现fianl的,既不可继承的。
/**
 * Constructs a string builder with no characters in it and an
 * initial capacity of 16 characters.
 */
public StringBuilder() {
    super(16);
}
当你创建了一个StringBuilder的时候,其长度默认为16,如果长度大于了16,
/**
 * Constructs a string builder initialized to the contents of the
 * specified string. The initial capacity of the string builder is
 * <code>16</code> plus the length of the string argument.
 *
 * @param   str   the initial contents of the buffer.
 * @throws    NullPointerException if <code>str</code> is <code>null</code>
 */
public StringBuilder(String str) {
    super(str.length() + 16);
    append(str);
}
StringBuilder会在16的基础上进行扩容。
/**
 * Constructs a string builder with no characters in it and an
 * initial capacity specified by the <code>capacity</code> argument.
 *
 * @param      capacity  the initial capacity.
 * @throws     NegativeArraySizeException  if the <code>capacity</code>
 *               argument is less than <code>0</code>.
 */
public StringBuilder(int capacity) {
    super(capacity);
}
你也可以自定义长度,但是长度不能小于0,否则会NegativeArraySizeException异常。
	
public StringBuilder append(boolean b) {
    super.append(b);
    return this;
}

public StringBuilder append(char c) {
    super.append(c);
    return this;
}

public StringBuilder append(int i) {
    super.append(i);
    return this;
}

public StringBuilder append(long lng) {
    super.append(lng);
    return this;
}

public StringBuilder append(float f) {
    super.append(f);
    return this;
}

public StringBuilder append(double d) {
    super.append(d);
    return this;
}
另外,你会发现StringBuilder不是线程安全的,所谓的线程安全就是在多线程的情况下,会出现多个多个append同时修改导致的结果不一致的不安全问题,因此如果要多线程使用StringBuilder的时候,要自己实现锁的问题。建议在单线程下使用StringBuilder。

三、StringBuffer

public final class StringBuffer
   extends AbstractStringBuilder
   implements java.io.Serializable, CharSequence{}
StringBuffer与StringBuilder在实现功能上市类似的,其主要区别在于,StringBuffer是线程安全的,
StringBuffer也是final的,不可继承的。并且是可变的,使用synchronized使线程安全了。
public synchronized StringBuffer append(Object obj) {
    super.append(String.valueOf(obj));
    return this;
}

public synchronized StringBuffer append(String str) {
    super.append(str);
    return this;
}
public synchronized StringBuffer append(boolean b) {
    super.append(b);
    return this;
}

public synchronized StringBuffer append(char c) {
    super.append(c);
    return this;
}

public synchronized StringBuffer append(int i) {
    super.append(i);
    return this;
}

四、总结

(1)String类型是被final修饰的,长度不可变的,即使使用concat方法,也是新创建了个对象,将值赋给了新的对象。
(2)StringBuilder是长度可变的,可以使用append方法增加长度,默认长度为16,但是线程不安全,速度快。
(2)StringBuffer是长度可变的,可以使用append方法增加长度,默认长度为16,是线程安全的,因为使用了所锁的作用,与StringBuilder相比的速度比较慢。
如有错误,请多多指教,谢谢,博主会再接再厉,写出更好的文章。

	



 
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值