请原谅初学者的问题。我在互联网上遇到了这段代码片段:
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;
}
}
我发现运行输出应该是A,A,但是,正确的输出应该是A,BA,专家可以帮助我理解为什么b的值仍然是AB?为什么“y.append(x)”会影响b的值,而不是“y = x”?这就是我感到困惑的地方。
提前致谢。
答案 0 :(得分:6)
简短的回答是Java参数是按值传递的,因此operate
中的最终赋值没有任何影响。
详细的事件顺序如下:
a
和b
被初始化为两个StringBuffer对象。让我们把它写成
a -> S1{"A"}
b -> S2("B")
评估operator
调用参数的(普通)参数表达式,给出S1 {“A”}和S2 {“B”}。
调用开始,两个引用分配给局部变量x
和y
。现在状态如下:
a -> S1{"A"}
x -> |
b -> S2("B")
y -> |
y.append(x)
调用会修改S2对象:
a -> S1{"A"}
x -> |
b -> S2("BA")
y -> |
执行y = x;
分配:
a -> S1{"A"}
x -> |
y -> |
b -> S2("BA")
operate
方法返回,导致x
和y
超出范围。
a -> S1{"A"}
b -> S2("BA")
需要注意的关键是在步骤5中我们不能更改S2对象的内容。相反,我们只是将y
更改为引用另一个对象。
答案 1 :(得分:0)
在该方法中,y=x
行仅更改局部变量y
,不会影响调用者范围中的b
变量。
更改操作方法中的b
变量,因为您无法将指针传递给java中的变量,这有点困难。你可以:
b = operate...
答案 2 :(得分:0)
Java不使用按名称调用或按引用调用。
void replace(Anything x) {
x = y;
}
无效,按定义,因为x
是 new 变量,而不是调用变量的别名。对变量x
的任何更改都仅限于方法范围。请注意,x.setSomething
可能仍会修改x
引用的内容。
这实际上适用于大多数编程语言。它避免了错误,并且有方法可以明确地实现所需的结果。
Java始终按值调用。即使使用引用,它们在技术上也作为值传递(对象引用类型)。
即。变量“Integer example;
”在技术上不是Integer
,但它是null
实例的引用(可能是Integer
)。 引用被复制(按值调用),但当然它之后仍然引用同一个对象。所以你可以修改对象,但你不能改变实际的引用,因为你只有它的副本。
答案 3 :(得分:0)
让干运行方法:
参考状态是
a -> A, x -> A, b -> B, y -> B.
append
执行
a -> A, x -> A, b -> BA, y -> BA.
y=x
执行
a -> A, x -> A, b -> BA, y -> A.
现在,打印输出应该是什么? : - )
要点是,