一道面试题,加深了我对java参数传递的理解

一道面试题:

public class Test {
    public static void main(String[] args) {
        StringBuffer stringBuffer = new StringBuffer("A");
        StringBuffer stringBuffer1 = new StringBuffer("B");
        operator(stringBuffer,stringBuffer1);
        System.out.println(stringBuffer+","+stringBuffer1);
        //输出:AB,B
    }

    private static void operator(StringBuffer stringBuffer, StringBuffer stringBuffer1) {
        stringBuffer.append(stringBuffer1);
        stringBuffer1 = stringBuffer;
    }


}

对于这个输出结果,我是一点准备都没有啊,我以为是AB,AB的。

我们都知道,java参数传递:

  1. 值传递,包括:基本数据类型(byte/short/int/long/float/double/char),String
  2. 引用排序,包括:对象(数组对象)

public class Test {
    public static void main(String[] args) {
        //基本数据类型
        int a = 1;
        char b = 'a';
        String c = "11";
        //数组、对象
        int[] d = new int[3];
        System.out.println(d[0]);
        StringBuilder str = new StringBuilder("haha");
        System.out.println(str);
        //方法传递参数
        operator(a,b,c,d,str);

        System.out.println(a+","+b+","+c+","+d[0]+","+str);
        //结果
        //0
        //haha
        //1,a,11,1,hahazzz
    }

    private static void operator(int a , char b,String c,int[] d,StringBuilder str){
        a = 10;
        b = 'h';
        c = "aaa";
        d[0] = 1;
        str.append("zzz");
    }

}

也就是说,传入到方法中的参数,如果是值传递的,你随便操作,都不会影响到原值;但是引用传递,你改变了这个对象,就会改变原值。
但是,为什么开篇的面试题不是输出AB,AB呢?(此时的我,对堆栈内存的理解不够深入)
网上有博客称:java中只有值传递!!!以前看到这种答案,我一笑置之,对象和数组明明是按引用传递的,哪来的菜鸟在这糊弄人呢,但是这种说法是对的。
基本数据类型,按值传递,把值复制一份传给方法后,就和自己没关系了,随你方法怎么改;对象类型(包括数组对象),我也是按值传递,我是把对象的引用(栈内存)按值复制一份传给方法,这时,栈中就有两个对象引用指向堆中同一个对象了,这时,你方法里面操作这个引用(比如,指向其他对象),对原引用没有影响,对堆中的对象也没有影响,但是你操作了堆中对象,就对原引用有影响了,这里我改变一下代码,并附上原理图一份,大家就懂开篇的案例了。

public class Test {
    public static void main(String[] args) {
        StringBuffer str = new StringBuffer("A");
        StringBuffer str1 = new StringBuffer("B");
        operator(str,str1);
        System.out.println(str+","+str1);
        //输出:AB,B
    }

    private static void operator(StringBuffer x, StringBuffer y) {
        x.append(y);
        y = x;
    }


}
[堆栈内存示意图]
文章目录
|