Java 通过引用传递
Posted
技术标签:
【中文标题】Java 通过引用传递【英文标题】:Java pass by reference 【发布时间】:2012-03-13 08:39:55 【问题描述】:这两个代码有什么区别:
代码 A:
Foo myFoo;
myFoo = createfoo();
在哪里
public Foo createFoo()
Foo foo = new Foo();
return foo;
对比。代码 B:
Foo myFoo;
createFoo(myFoo);
public void createFoo(Foo foo)
Foo f = new Foo();
foo = f;
这两段代码有区别吗?
【问题讨论】:
那里没有“通过引用”。它是按值传递的,值是一个引用。代码 B 无法编译,如果可以,它也不会改变 myFoo。 【参考方案1】:Java 总是按值而不是按引用传递参数。
让我通过example 解释一下:
public class Main
public static void main(String[] args)
Foo f = new Foo("f");
changeReference(f); // It won't change the reference!
modifyReference(f); // It will modify the object that the reference variable "f" refers to!
public static void changeReference(Foo a)
Foo b = new Foo("b");
a = b;
public static void modifyReference(Foo c)
c.setAttribute("c");
我将分步解释:
声明一个名为f
类型为Foo
的引用并将其分配给一个类型为Foo
的新对象,其属性为"f"
。
Foo f = new Foo("f");
在方法方面,声明了一个名为 a
的类型为 Foo
的引用,并且它最初分配给 null
。
public static void changeReference(Foo a)
当您调用方法changeReference
时,引用a
将分配给作为参数传递的对象。
changeReference(f);
声明一个名为b
类型为Foo
的引用,并将其分配给一个类型为Foo
的新对象,其属性为"b"
。
Foo b = new Foo("b");
a = b
正在将引用 a
NOT f
重新分配给其属性为 "b"
的对象。
当您调用modifyReference(Foo c)
方法时,会创建一个引用c
并将其分配给具有"f"
属性的对象。
c.setAttribute("c");
会改变引用c
指向它的对象的属性,和引用f
指向它的对象是同一个对象。
我希望您现在了解在 Java 中如何将对象作为参数传递:)
【讨论】:
您能对比一下“通过引用传递”的样子吗?对我来说有意义的是“按值传递”,它传递 f 引用的对象的内存地址。在 changeReference 中,a 是一个新变量,它引用同一个内存地址,只改变 a 的值(或引用的内存地址)更改 a 指向的内容,而不是 f。如果它是“通过引用传递”,f 将被传入,所以 a = f,改变 a 的值(或引用的内存地址)会改变 f【参考方案2】:由于 Java 严格“按值传递”,甚至对对象的引用也是按值传递的,因此第二个代码将无法按预期工作。请参阅右侧的“相关”部分,了解关于此的众多讨论。
【讨论】:
【参考方案3】:将方法参数视为它们自己的变量声明。如果你用一个代码块代替方法调用,它看起来像这样:
Foo myFoo;
//Method call starts here
Foo foo;
foo = myFoo;
Foo f = new Foo();
foo = f;
//Method call ends here
即使方法参数与另一个变量同名,方法参数仍然是它自己的,只有方法知道的唯一引用。这与 Eng.Fouad 上面所说的相同。
【讨论】:
【参考方案4】:您应该知道的另一个重要点是您传递给方法的对象类型。无论是可变对象还是不可变对象。如果您传递一个不可变对象(例如 String),它将创建另一个副本并进行修改。更改不会反映在您的原始副本中。
【讨论】:
不,语言中没有“可变”或“不可变”的概念。因此,它们的传递方式没有区别。 “更改不会反映在您的原始副本中。”根据定义,不可变对象是没有方法可以“改变”的对象,因此这种说法没有意义。以上是关于Java 通过引用传递的主要内容,如果未能解决你的问题,请参考以下文章