Java 是否通过引用传递?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/589919/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Does Java pass by reference?
提问by Scott Stanchfield
Does Java really support passing by reference?
Java 真的支持按引用传递吗?
If it doesn't, why do we have the == operator for finding two objects with the same reference?
如果不是,为什么我们要使用 == 运算符来查找具有相同引用的两个对象?
回答by pgras
Java uses pass by value, not by reference...
Java 使用按值传递,而不是按引用传递...
But, for non primitive types the value is the value of the reference.
但是,对于非原始类型,该值是引用的值。
So == compares the values of references for Objects.
所以 == 比较对象的引用值。
回答by Scott Stanchfield
For a detailed explanation, see my article "Java is Pass-By-Value, Dammit!"
详细解释请看我的文章“Java is Pass-By-Value,该死!”
回答by joel.neely
The point of distinction is between "pass**-by-reference" and "passing a** reference". You also sometimes see "call-by-..." and "pass-by-..." used interchangeably. For simplicity, I'll stick with "pass-by-...".
区别在于“通过引用传递** ”和“传递**引用”。您有时还会看到“call-by-...”和“pass-by-...”可以互换使用。为简单起见,我将坚持使用“pass-by-...”。
In academic, old-school, FORTRAN-relevant, comp-sci terminology, pass-by-referencemeans that the called code has access (reference) to a variable passed by the caller. Assigning to the formal parameter in the called code actually does an assignment to the caller's variable. The distinction is versus (among others) pass-by-value, which gives the called code a copy of the data (whatever it is) known to the caller.
In the contemporary Java-relevant, OO world, "having a reference" to an object means being able to get to the object itself. This is distinguished from "having a pointer" to emphasize (among other things) that one doesn't do "pointer arithmetic" on a reference. (In fact, a "reference" in this sense does not necessarily have to be an actual pointer-like memory address.)
在学术的、老式的、与 FORTRAN 相关的、comp-sci 术语中,传递引用意味着被调用的代码可以访问(引用)调用者传递的变量。对被调用代码中的形参赋值实际上是对调用者的变量进行赋值。区别在于(以及其他)pass-by-value,它为被调用的代码提供了调用者已知的数据(无论它是什么)的副本。
在当代与 Java 相关的 OO 世界中,对对象的“引用”意味着能够访问对象本身。这与“有一个指针”不同,以强调(除其他外)一个人不会对引用进行“指针算术”。(实际上,这种意义上的“引用”不一定是实际的类似指针的内存地址。)
Java passes arguments by value (in the first sense), but for object arguments, the value is a reference (in the second sense). Here's a bit of code that relies on the difference.
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);
...
Upon return from munge, the caller's first list, l0will contain "Goodbye". A reference to that list was passed to munge, which called a mutating method on that referred-to object. (In other words, a0received a copyof the value of l0, which was a reference toa string list that got modified.)
从 返回后munge,调用者的第一个列表l0将包含"Goodbye"。对该列表的引用被传递给munge,它在该被引用的对象上调用了一个变异方法。(换句话说,a0收到了的值的副本l0,它是对已修改的字符串列表的引用。)
However, upon return from munge, the caller's second list, l1still contains "world"because no methods were called on the passed object reference (the value of l1, passed by valueto munge). Instead, the argument variable a1got set to a new value (the local object reference also held in foo).
但是,在从 返回时munge,调用者的第二个列表l1仍然包含 ,"world"因为没有对传递的对象引用( 的值l1,通过值传递给munge)调用任何方法。相反,参数变量a1被设置为一个新值(本地对象引用也保存在 中foo)。
IFJava had used pass-by-reference, then upon return, l1would have contained "everybody"because a1would have referred to the variablel1and not simply been initialized to a copy of its value. So the assignment to a1would have also been an assignment to l1.
如果Java 使用了引用传递,那么在返回时,l1将包含"everybody"因为a1将引用变量l1而不是简单地初始化为其值的副本。因此,分配给a1也将分配给l1。
This same issue was discussed in another question, with ASCII-art to illustrate the situation.
在另一个问题中讨论了同样的问题,用 ASCII-art 来说明这种情况。
回答by Yuval Adam
Java does notuse pass-by-reference but rather pass-by-value. Primitive value parameters are copiedto the stack, as well as pointers to objects.
Java不使用按引用传递,而是按值传递。原始值参数以及指向对象的指针被复制到堆栈中。
The ==operator should be used for comparing primitive values, and for comparing object references.
的==操作者应该用于比较的原始值,以及用于比较的对象的引用。
回答by javashlook
Short answer is no. In Java there is only pass-by-value, and when you are working with objects (e.g. Object obj = new Object();), you are working with object references. Which get passed by value.
简短的回答是否定的。在 Java 中只有按值传递,当您使用对象(例如Object obj = new Object();)时,您正在使用对象引用。通过值传递。
For details, see: Parameter passing in Java
详见:Java中的参数传递

