如何在Java中识别pass-by-value或pass-by引用?

Kev*_*vin 1 java

请原谅初学者的问题.我在互联网上遇到了这段代码片段:

public class Person {

public static void main(String [] args)
{
    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)
{
    y.append(x);
    y=x;

 }
}
Run Code Online (Sandbox Code Playgroud)

我想出运行输出应该是A,A,但是,正确的输出应该是A,BA,请问专家帮助我理解为什么b的值仍然是AB?为什么"y.append(x)"会影响b的值,而不是"y = x"?这就是我感到困惑的地方.

提前致谢.

Ste*_*n C 6

简短的回答是Java参数是按值传递的,因此最终的赋值operate没有任何影响.

详细的事件顺序如下:

  1. ab初始化为两个StringBuffer对象.让我们写这个

     a -> S1{"A"}
     b -> S2("B")
    
    Run Code Online (Sandbox Code Playgroud)
  2. operator调用调用参数的(普通)参数表达式,给出S1 {"A"}和S2 {"B"}.

  3. 调用开始,两个引用分配给局部变量xy.现在状态如下:

     a -> S1{"A"}
     x -> |
    
     b -> S2("B")
     y -> |
    
    Run Code Online (Sandbox Code Playgroud)
  4. y.append(x)调用修改了S2对象:

     a -> S1{"A"}
     x -> |
    
     b -> S2("BA")
     y -> |
    
    Run Code Online (Sandbox Code Playgroud)
  5. y = x;执行任务:

     a -> S1{"A"}
     x -> |
     y -> |
    
     b -> S2("BA")
    
    Run Code Online (Sandbox Code Playgroud)
  6. operate方法返回,导致xy超出范围.

     a -> S1{"A"}
     b -> S2("BA")
    
    Run Code Online (Sandbox Code Playgroud)

需要注意的关键是在步骤5中我们不能改变S2对象的内容.相反,我们只是改为y引用另一个对象.