public class wo{
public static void main (String args[]) throws IOException
{
 StringBuffer a = new StringBuffer ("A"); 
 StringBuffer b = new StringBuffer ("B"); 
 operate (a,b); 
 System.out.println(a+"    "+b);

 static void operate (StringBuffer x, StringBuffer y) { 
 x.append(y);
 y = x; 
 }
}
输出AB   B
为什么?

解决方案 »

  1.   

    这个问题很早就见过,好象是JAVA文档里说过,StringBuffer不支持引用的传递.
      

  2.   

    static void operate (StringBuffer x, StringBuffer y) 这里的x y 只是个引用, 他的作用域仅仅在{}之间, 一旦方法结束就会被指为空引用,等待垃圾回收器日后清理. x.append(y); 这句是起作用的,因为那时x还是new StringBuffer ("A"); 的一个引用,和a地位一样,但和a没有必然的联系,对象内容由于append的作用而发生了改变.同样,y和b一样是new StringBuffer ("B");的引用,他们之间也没有直接联系. y = x 虽然把y的引用指向了x的引用,但和a与b没有任何关系.a还是指向原来的对象,b也仍然还是指向原来的对象. 一旦operate方法结束x,y就失效了.这和StringBuffer没有关系 换作任意对象这样引用都会这样. 要改变引用必须 b = a(要理解 a,b,x,y是独立的平等的 都是普通的引用 之间没有任何关系 只是作用域不同)
      

  3.   

    string不也是传引用么
    String m="fsd";
     m.concat("b");
     System.out.println(m);
    输出的还是fsd
    我是不是可以这么理解,m.concat("b")相当于重新new了一个string并给它分配了空间
    如果是的话,那我上面的 x.append(y);为什么不可以这样理解啊?
    有谁知道底层的机制么?
      

  4.   

    x.append(y);//改变了a 的内容,
    y = x;b的内容没有变引用的问题了
      

  5.   

    有时候是我们自己把问题讲复杂了
    其实问题很简单,只要了解如下基本知识:
    1、变量类型
    值 变 量:用于代表存储大小确定的值
    引用变量:用于代表存储大小不定的值
    2、变量存储
    栈:分配的存储空间不可改变,在超过作用域后能够自动回收
    堆:分配的存储空间可以改变,在超过作用域后需要垃圾回收
    值 变 量:只在栈中申请一个与自己值域匹配的空间,用于存放自身的值
    引用变量:先在栈中申请一个与 CPU 寻址能力匹配的空间,用于存放一个地址值
         再在堆中申请一个存放自身实例的空间,并把这个空间的首地址放入栈中预先申请的空间
    变量名:都是程序代码中栈空间的首地址的代表,程序编译时,变量名会被替换为相对于栈首地址的偏移量
    3、方法的参数传递
    值 传 递:方法的形参申请自己的存储空间,运行时把方法调用时的实参值复制给形参的方式
    引用传递:方法的形参不申请自己的存储空间,让方法的形参与实参共享同一存储地址的方式
    4、Java的参数传递方式:值传递
    对于值参数,把实参值复制给形参,所以值参传递时形参在方法中的改变不影响实参。
    对于引用参数,也是把实参值复制给形参,只是这次复制的值是实参的栈空间中存放的值(栈中存了堆中的首地址值),也就是说:实参与形参将共用同一个堆空间。为此:
    方法中如果改变了堆空间中的内容,实参能同步改动;
    方法中如果改变了形参本身的栈中值(存放了一个新的堆空间首地址值),由于是值传递,实参是不变的本例中:
    x.append(y);//把形参y的实例值加到形参x实例值中,改变的是形参x堆空间中的内容,a同步改动
    y=x;//把形参x的栈中值复制给形参y,使x、y共用同一堆空间,改变的是形参y栈空间中的内容,b不变
      

  6.   

    谢谢welshem(天堂客) 
    我明白了,感激不尽啊!!!!
      

  7.   

    典型的传值和传地址问题楼上说得都很清楚了,不重复了.
    package test;public class test {

    public static void main(String ... s)
    {
    int[] arr = {1,2,4,3,5,6};
    System.out.println(arr[2] + "," + arr[3]);
                      /*交换下标为2,3两个数*/
    swap(arr,2,3);
    System.out.println(arr[2] + "," + arr[3]);
    }

    public static void swap(int[] arr,int x,int y)
    {
    int tmp; 
    tmp = arr[x];
    arr[x] = arr[y];
    arr[y] = tmp;
    }
    }