在 Java 中,经常会出现关于对象传递机制的误解。本文将深入探讨两个代码片段之间的区别,阐明 Java 参数传递行为的基本原理。
代码 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; }
与流行的看法相反,Java 使用按值传递,而不是按值传递通过参考。这意味着当一个对象作为参数传递时,会创建其引用的副本,而不是直接引用原始对象。
在第一行中,myFoo 是已声明但未分配。第二行调用 createFoo 方法,该方法返回分配给 myFoo 的新 Foo 对象。此赋值创建一个与该方法中创建的对象不同的新对象。
相反,代码 B 将 myFoo 引用作为参数传递给 createFoo 方法。在该方法中,创建一个新的 Foo 对象并将其分配给 foo 参数。随后,foo 被分配给 a,它是方法内的局部变量。此重新分配有效地修改了本地引用 foo,而不是原始引用 myFoo。
为了说明概念,请考虑以下类:
public class Foo { private String attribute; public void setAttribute(String attribute) { this.attribute = attribute; } }
主类:
public class Main { public static void main(String[] args) { Foo f = new Foo("f"); changeReference(f); // Attempt to change reference modifyReference(f); // Attempt to modify object attribute } public static void changeReference(Foo a) { Foo b = new Foo("b"); a = b; } public static void modifyReference(Foo c) { c.setAttribute("c"); } }
main方法创建Foo的实例并将其分配给f后,它调用changeReference,它尝试将a引用重新分配给不同的对象。但是,这不会改变 f 引用。
相反,modifyReference 修改 c 引用的对象的属性,该对象与 f 是同一个对象。这表明引用传递创建的是引用的副本,而不是对象本身。
Java 的值传递方法通过保护原始对象免遭其范围之外的无意修改来确保对象不变性。这一原则促进了封装并有助于创建健壮且可预测的代码。
以上是Java 是按值还是按引用传递对象?的详细内容。更多信息请关注PHP中文网其他相关文章!