Java真的支持通过引用传递吗?
如果没有,为什么我们有==运算符来查找具有相同引用的两个对象?
答案 0 :(得分:15)
Java使用pass by value,而不是引用...
但是,对于非原始类型,该值是引用的值。
所以==比较对象的引用值。
答案 1 :(得分:11)
有关详细说明,请参阅我的文章“Java is Pass-By-Value,Dammit!”
答案 2 :(得分:5)
区别在于“传递** - 按 - <强>参考”和“传递进行**参考”。您有时也会看到“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
中)。
IF Java使用了传递引用,然后在返回时,l1
将包含"everybody"
,因为a1
会引用变量 l1
而不是简单地初始化为其值的副本。因此,对a1
的分配也是对l1
的分配。
在another question中讨论了同样的问题,用ASCII-art来说明情况。
答案 3 :(得分:3)
Java 不使用pass-by-reference,而是使用pass-by-value。原始值参数复制到堆栈,以及指向对象的指针。
==
运算符应该用于比较原始值和比较对象引用。
答案 4 :(得分:2)
简短的回答是否定的。在Java中,只有pass-by-value,当你使用对象(例如Object obj = new Object();
)时,你正在使用对象引用。哪个值得通过。
有关详细信息,请参阅:Parameter passing in Java