如何在Java中按值传递变量?

3

我对Java还很陌生,但我在PHP方面有丰富的经验。当我编写Java程序时,我注意到变量不是我所期望的。

在Java中,所有方法参数都是按值传递的。然而,由于所有对象实际上都是引用,因此在传递对象时,您传递的是引用的值。这意味着如果您操纵传递到方法中的对象,则操作将保留。

来自:PHP和Java之间的区别是什么?

这是什么意思?这是否意味着Java中的foo=blah就像PHP中的$foo=&$blah?如何在Java中只传递值?


以下是它的工作原理示例:https://dev59.com/QnVD5IYBdhLWcg3wWaVh - Michael
1
Java 中没有“按引用传递”的概念。Java 总是按值传递。https://dev59.com/EXVD5IYBdhLWcg3wQJOT - Matt Ball
我会阅读评估策略。虽然Java只实现了“按值调用”,但传递对象值的语义可以理解为“按对象共享调用”。(实际上:当您传递一个对象时,您传递的是那个对象,而不是副本。)Java完全缺乏PHP具有的变量引用概念,这与“按引用调用”类似但又不同。 - user166390
2个回答

5
这句话的意思是,假设给定...
 class Foo { 
     private int bar; 

     public void setBar(int value) {
         bar = value;
     }

     public int getBar() {
         return bar;
     }
 }

并且
public void doSomethingToFoo(Foo foo) {
     foo.setBar(42);
}

更改 bar 将在调用处可见。这是一个持续的操作。对原始对象的引用被传递进去了。该对象的 setter 被调用,因此调用处的 getter 将返回 bar 的新值。

Foo foo = new Foo();
doSomethingToFoo(foo);
int bar = foo.getBar(); // gets 42

然而,鉴于

public void doSomethingElseWithFoo(Foo foo) {
     foo = new Foo(); // assigning new instance to variable
     foo.setBar(117);
}

这个改变在调用端是看不到的,因为方法内部的 foo 变量已经被重新赋值。引用仅被按值传递,这些变量实际上并没有任何连接或关联,它们只是共享了一个值(即引用)。我们现在已经覆盖了方法内部一个变量拥有的引用,调用端的变量仍然拥有之前相同的引用。

Foo foo = new Foo();
foo.setBar(7);
doSomethingElseWithFoo(foo);
int bar = foo.getBar(); // still is 7!

这个有意义吗?


2

Anthony Pegram已经很好地解释了。

我想再补充一点。

你永远无法通过值传递对象。

在Java中,每个对象都是在堆中创建的。您有一个引用或者我们可以说是一个梯子来到达该对象。在函数调用的情况下,您将引用(按值)作为参数传递。因此,您在函数中有另一个指向相同对象的引用或梯子。您可以通过此引用访问该对象并对其进行更改。现在,如果您像Anthony那样更改了函数中的引用

 foo = new Foo();

发生了什么,您刚在堆中创建了一个新对象,并且具有该对象的引用。在此步骤中,您将现有引用(对旧对象的引用)替换为新创建对象的引用。因此,在您的函数中,您失去了访问旧对象的方式。现在,如果您进行任何更改,则更改的是新创建的对象,而不是调用函数的对象。

谢谢。


不错的回答。你需要知道的是,关于Java参数是否按引用传递对象或按值传递引用,SO上已经发生了激烈的争论。我觉得最好避免这个争论,除非你不能回答问题而不持任何一方立场。 - Mike Samuel

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接