String和StringBuffer源码区别

           最近忽然想起来这个很简单的东西,看到挺多很对这个存在一些疑问,我就写了这个自己的理解。主要解决string和stringbuffer有什么区别,为什么string是不可变的,stringbuffer是可变的。我通过源码层面帮助大家理解。


1.StringBuffer继承AbstractStringBuilder,char数组没有final修饰。

abstract class AbstractStringBuilder implements Appendable, CharSequence {
    /**
     * The value is used for character storage.
     */
    char[] value;

    /**
     * Creates an AbstractStringBuilder of the specified capacity.
     */
    AbstractStringBuilder(int capacity) {
        value = new char[capacity];
}



2.而StringBuffer继承了AbstarctStringBuilder,他的char数组用的是他的父类AbstarctStringBuider.

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

    /** use serialVersionUID from JDK 1.0.2 for interoperability */
    static final long serialVersionUID = 3388685877147921107L;

    /**
     * Constructs a string buffer with no characters in it and an
     * initial capacity of 16 characters.
     */
    public StringBuffer() {
        super(16);
    }

    /**
     * Constructs a string buffer with no characters in it and
     * the specified initial capacity.
     *
     * @param      capacity  the initial capacity.
     * @exception  NegativeArraySizeException  if the <code>capacity</code>
     *               argument is less than <code>0</code>.
     */
    public StringBuffer(int capacity) {
        super(capacity);
    }

    /**
     * Constructs a string buffer initialized to the contents of the
     * specified string. The initial capacity of the string buffer is
     * <code>16</code> plus the length of the string argument.
     *
     * @param   str   the initial contents of the buffer.
     * @exception NullPointerException if <code>str</code> is <code>null</code>
     */
    public StringBuffer(String str) {
        super(str.length() + 16);
        append(str);
    }
    public synchronized StringBuffer append(String str) {
        super.append(str);
        return this;
    }



3.String用的char数组被final修饰,也就是说被构造函数赋值之后就不能再次赋值。所以,String不能再次赋值。

public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence {
    /** The value is used for character storage. */
    <span style="color:#ff0000;">private final char value[];</span>

    /** Cache the hash code for the string */
    private int hash; // Default to 0

    /**
     * Initializes a newly created {@code String} object so that it represents
     * the same sequence of characters as the argument; in other words, the
     * newly created string is a copy of the argument string. Unless an
     * explicit copy of {@code original} is needed, use of this constructor is
     * unnecessary since Strings are immutable.
     *
     * @param  original
     *         A {@code String}
     */
    public String(String original) {
        this.value = original.value;
        this.hash = original.hash;
}

4.既然String是不可变字符串对象,如何才能改变让其可变?

通过Java中的反射机制实现。因此,前文中说到的String是不可变字符串对象只是针对“正常情况下”。而非必然。
public static void stringReflection() throws Exception {
 
      String s = "Hello World";
  
     System.out.println("s = " + s); //Hello World
 
      //获取String类中的value字段
      Field valueField = String.class.getDeclaredField("value");
  
     //改变value属性的访问权限
     valueField.setAccessible(true);
 
     char[] value = (char[]) valueField.get(s);
 
     //改变value所引用的数组中的第5个字符
     value[5] = '_';
 
     System.out.println("s = " + s); //Hello_World
 }






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值