Java真的支持引用传递吗?
如果没有,为什么我们要使用 == 运算符来查找具有相同引用的两个对象?
Java 使用按值传递,而不是按引用传递...
但是,对于非原始类型,值是引用的值。
所以 == 比较对象的引用值。
区别在于“通过**引用”和“通过**引用”。您有时还会看到“call-by-...”和“pass-by-...”可以互换使用。为简单起见,我将坚持使用“pass-by-...”。
在学术的、老式的、与 FORTRAN 相关的、comp-sci 术语中,按引用传递意味着被调用的代码可以访问(引用)调用者传递的变量。赋值给被调用代码中的形参实际上是对调用者的变量进行赋值。区别在于(除其他外)传递值,它为被调用代码提供调用者已知的数据(无论是什么)的副本。
在当代与 Java 相关的 OO 世界中,对对象的“引用”意味着能够访问对象本身。这与“有一个指针”不同,以强调(除其他外)一个人不对引用进行“指针算术”。(实际上,这种意义上的“引用”不一定是实际的类似指针的内存地址。)
Java 通过值传递参数(在第一种意义上),但对于对象参数,值是一个引用(在第二种意义上)。这是一些依赖于差异的代码。
// called
public void munge(List<String> a0, List<String> a1) {
List<String> foo = new List<String>(); foo.add("everybody");
a0.set(0, "Goodbye");
a1 = foo;
}
// caller
...
List<String> l0 = new List<String>(); l0.add("Hello");
List<String> l1 = new List<String>(); l1.add("world");
munge(l0, l1);
...
从 调用返回后munge
,调用者的第一个列表l0
将包含"Goodbye"
. 对该列表的引用被传递给munge
,它在该被引用对象上调用了一个变异方法。(换句话说,a0
收到的值的副本l0
,它是对已修改的字符串列表的引用。)
但是,在从munge
调用者的第二个列表返回时,l1
仍然包含,"world"
因为没有在传递的对象引用上调用任何方法( 的值l1
,按值传递给munge
)。相反,参数变量a1
被设置为一个新值(本地对象引用也保存在 中foo
)。
如果Java 使用了传递引用,那么在返回时,l1
将包含"everybody"
,因为a1
会引用变量 l1
而不是简单地初始化为其值的副本。因此,对的分配a1
也将是对的分配l1
。
在另一个问题中讨论了同样的问题,用 ASCII-art 来说明这种情况。
Java不使用按引用传递,而是按值传递。原始值参数被复制到堆栈中,以及指向对象的指针。
==
运算符应该用于比较原始值和比较对象引用。
简短的回答是否定的。在Java 中只有值传递,当您使用对象(例如Object obj = new Object();
)时,您正在使用对象引用。哪个按值传递。
详见:Java中的参数传递