如何在Java中识别按值传递或按引用传递?

如何在Java中识别按值传递或按引用传递?,java,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 ope

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

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.appendx会影响b的值,而不是y=x?这就是我感到困惑的地方

提前感谢。

在该方法中,y=x行仅更改局部变量y,不影响调用者范围内的b变量

在operate方法中更改b变量有点困难,因为在java中无法向变量传递指针。你可以:

返回它:b=操作。。。 更改其内容,但这将是一个副本 在该方法中,y=x行仅更改局部变量y,而不影响调用者范围中的b变量

在operate方法中更改b变量有点困难,因为在java中无法向变量传递指针。你可以:

返回它:b=操作。。。 更改其内容,但这将是一个副本
简而言之,Java参数是按值传递的,因此operate中的最终赋值没有任何效果

事件的详细顺序如下:

a和b初始化为两个StringBuffer对象。让我们把它写成

 a -> S1{"A"}
 b -> S2("B")
运算符调用参数的平凡参数表达式在给出S1{A}和S2{B}时进行求值

调用开始,两个引用被分配给局部变量x和y。因此,国家现在:

 a -> S1{"A"}
 x -> |

 b -> S2("B")
 y -> |
y.appendx调用修改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改为引用另一个对象。

简单的回答是Java参数是按值传递的,因此operate中的最终赋值没有任何效果

事件的详细顺序如下:

a和b初始化为两个StringBuffer对象。让我们把它写成

 a -> S1{"A"}
 b -> S2("B")
运算符调用参数的平凡参数表达式在给出S1{A}和S2{B}时进行求值

调用开始,两个引用被分配给局部变量x和y。因此,国家现在:

 a -> S1{"A"}
 x -> |

 b -> S2("B")
 y -> |
y.appendx调用修改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改为引用另一个对象。

Java不使用名称调用或引用调用

根据定义,不执行任何操作,因为x是一个新变量,而不是调用变量的别名。对变量x的任何更改都限制在方法范围内。请注意,x.setSomething仍可能修改x引用的内容

这实际上适用于大多数编程语言。它避免了错误,并且有明确实现所需结果的方法

Java总是按值调用。即使在使用引用时,它们在技术上也是作为对象引用类型的值传递的

即可变整数示例;从技术上讲,它不是整数,但它是对整数实例的引用,可以为null。引用是按值复制的,但当然,它之后仍然引用相同的对象。因此,您可以修改对象,但不能更改实际引用,因为您只有它的副本。

Java不使用按名称调用或按引用调用

根据定义,不执行任何操作,因为x是一个新变量,而不是调用变量的别名。对变量x的任何更改都限制在方法范围内。请注意,x.setSomething仍可能修改x引用的内容

这实际上适用于大多数编程语言。它避免了错误,并且有明确实现所需结果的方法

Java总是按值调用。即使在使用引用时,它们在技术上也是作为对象引用类型的值传递的


即可变整数示例;从技术上讲,它不是整数,但它是对整数实例的引用,可以为null。引用是按值复制的,但当然,它之后仍然引用相同的对象。因此,您可以修改对象,但不能更改实际引用,因为您只有它的一个副本。

让我们干运行operate方法:

参考状态为 a->a,x->a,b->b,y->b

追加执行 a->a,x->a,b->BA,y->BA

y=x执行 a->a,x->a,b->BA,y->a

现在,打印输出应该是什么-

要点是,

Java是按值传递的
.

让干运行操作方法:

参考状态为 a->a,x->a,b->b,y->b

追加执行 a->a,x->a,b->BA,y->BA

y=x执行 a->a,x->a,b->BA,y->a

现在,打印输出应该是什么-

要点是,

Java是按值传递的
.

那么为什么y.appendx会影响b?它仍然在本地方法中操作,它不影响变量,但传递的对象和引用保留在外部范围中。那么为什么y.appendx会影响b?它仍然在本地方法operate中,它不影响变量,但传递的对象和引用保留在外部范围中。请尝试在标题中添加更多实际信息,而不是帮助我理解。这样的标题完全没有用!从技术上讲,Java总是按值传递。对于除基本对象以外的所有对象,它都按值传递引用。请尝试在标题中添加更多实际信息,而不仅仅是帮助我理解。这样的标题完全没有用!从技术上讲,Java总是按值传递。对于除基本对象以外的所有对象,它都按值传递引用。谢谢。我唯一的问题是在步骤4中,为什么y.appendx修改S2,而y=x不修改S2?答案是,这就是Java赋值处理引用类型的方式;i、 e.对象和数组。您指定的是参考,而不是复制RHS上的内容而不是LHS上的内容。谢谢。我唯一的问题是在步骤4中,为什么y.appendx修改S2,而y=x不修改S2?答案是,这就是Java赋值处理引用类型的方式;i、 e.对象和数组。您分配的是引用,而不是复制RHS上的内容而不是LHS上的内容。我认为您的意思是Java不使用引用调用。据我所知,只有一种编程语言使用了真正的按名称调用,那就是Algol-60。C/C++预处理器宏也非常接近,尽管不是真的,我猜是按名称调用。我想你的意思是Java不使用按引用调用。据我所知,只有一种编程语言使用了真正的名称调用,那就是Algol-60。C/C++预处理器宏也非常接近,尽管我猜不是真正的名称调用。