解决方案 »

  1.   

    变的只有sb里的value属性,不是sb。
      

  2.   

    咦~~为毛你看的源码跟我看的源码不一样的。
    我看到的是直接调用AbstractStringBuilder的append方法就完事了:
    public AbstractStringBuilder append(String str) {
            if (str == null) str = "null";
            int len = str.length();
            ensureCapacityInternal(count + len);
            str.getChars(0, len, value, count);
            count += len;
            return this;
        }BTW,楼上正解!
      

  3.   

    继续看扩容的源码啊ensureCapacityInternal()=>expandCapacity()==>>"value = Arrays.copyOf(value, newCapacity);"==>>copyOf()最后是通过数组复制方法Arrays.copyOf()来完成扩容的,此时就新建了char[]数组,我是这一点不懂得理解,明明有新建了个缓冲char[] 数组,最后怎么又指向了最初的value区域??
      

  4.   

    value = new char[capacity];
    数组是定长的,你怎么直接变它?是通过新建一个长一点的数组,然后进行数组复制,再赋值,源码继续看下去
      

  5.   

            int[] ary=new int[]{1,2,3};
            System.out.println("ary原内存区域:"+ary);
            ary=Arrays.copyOf(ary,ary.length+1);
            System.out.println("ary扩容后内存区域:"+ary);
    很明显扩容前后ary数组的位置不同,如果是这样,我帖子中最后一段代码,方法传址就解释不了最后的结果。
      

  6.   

    不觉得有什么不对的,我们访问的是sb,又不是数组,sb不变,不管它指向哪个数组我们访问它都同样变化.
      

  7.   

    数组是引用类型,value属性的引用值放在sb对象的堆内存中, 执行sb.value = new char[];时,value的引用值发生变化指向了新的内存地址,这个变化是直接反映在堆上的
      

  8.   

    会不会是value和copy的内存地址一样的?value=Arrays.copyOf()时候,value重新指向了copy,而废弃了原来的引用地址
      

  9.   

    这么多概念名词。
    就这样,你看看怎么解释吧。
    char[] a = new char[10];
    char[] b = new char[20];
    a = b;
      

  10.   

    你可以测试一下,sb调用append方法后,即使发生了扩容,它也是指向原来的区域,这才是我纠结的地方,从底层源码看不出来。
      

  11.   

    我也是这么理解源码中的copyOf方法的,但是这样与调用append方法的结果不同,StringBuilder扩容后还是指向原来的区域
      

  12.   

    sb是指向原来的区域,
    但sb的value不是啊。
      

  13.   

            StringBuilder sb=new StringBuilder(),sbOrg;
            sbOrg=sb;
            System.out.println("扩容前sb容量"+sb.capacity());
            sb.append("aaaaaaaaaaaaaaaaaa");
            System.out.println("扩容后sb容量"+sb.capacity());
            System.out.println(sbOrg);
            System.out.println(sb);
    append方法扩容前后指向的是同一片区域,引用变量的赋值问题我知道,就是因为知道才有疑惑
      

  14.   

    好吧,一语惊醒梦中人,自己给自己绕进去了,3Q
    sb的区域存了一个引用变量value,value指向了实际存储的区域,在扩容时,value指向了新区域
      

  15.   


    public class MainClass { public static void main(String[] args) throws Exception {
    MainClass mc = new MainClass();
    MyStringBuffer msb = new MyStringBuffer();
    System.out.println(msb);
    mc.stringBufferAppend(msb);
    System.out.println(msb);
    System.out.println(Arrays.toString(msb.value));
    }

    void stringBufferAppend(MyStringBuffer sbTemp){  
            sbTemp=sbTemp.append("aaaaaaaaaaaaaaaaaa");  
        }  
    }class MyStringBuffer{
    char[] value={'b'};

    public MyStringBuffer append(String str)
    {
    char[] copy = new char[str.length()+value.length];
     
    System.arraycopy(value, 0, copy, 0, value.length);
    System.arraycopy(str.toCharArray(), 0, copy, value.length, str.length());
            value= copy;
    return this;
    }
    }看看我这个例子
      

  16.   

    你可以测试一下,sb调用append方法后,即使发生了扩容,它也是指向原来的区域,这才是我纠结的地方,从底层源码看不出来。
    你确定?sb和value是不一样的喔