Java中的数组是按引用传递还是按值传递?
Java中的数组是按引用传递还是按值传递?(我之前也曾问过类似的问题,但似乎没有一个很好的答案,所以希望这次会有所不同.)
Are arrays in java pass by reference or pass by value? (I've similar questions asked before, but none of them seemed to get a good answer, so hopefully this time will be different).
假设我有一个名为 data
的数组,其中包含某种类型的对象.现在让我们假设我将该数组传递并存储在A类中,然后将其传递给B类,而B类更改了该数组的一项.数组的A类版本会改变吗?它是否是原始数组(例如 int
)的数组,这有关系吗?ArrayLists呢?
Suppose I have an array called data
that contains Objects of some type. Now let us suppose that I pass and store that array in class A and then I pass it to class B and class B changes one of the entries of the array. Will class A's version of the array change? Does it matter if this was an array of primitives (such as int
) instead? What about ArrayLists?
谢谢
Java中的所有内容都是按值传递的.但是,如果要传递参考,则为参考的值.
Everything in Java is pass-by-value. However, if you're passing a reference, it's the value of the reference.
由于Java方法无法到达调用者的堆栈中以重新分配变量,因此任何方法调用都不能在那里更改引用(地址)的标识.这就是我们说Java不是按引用传递时的意思.这与C ++(和类似的语言)形成对比,后者在某些情况下允许这样做.
Since Java methods can't reach into the caller's stack to reassign variables, no method call can change the identity of a reference (address) there. This is what we mean when we say Java is not pass-by-reference. This contrasts with C++ (and similar languages), which allows this in some cases.
现在让我们来看一些效果.
Now let's look at some effects.
如果我这样做:
Object[] o = ...
mutateArray(o);
内容之后可能会有所不同,因为所有 mutateArray
所需的内容都是更改其内容的数组的地址.但是, o
的地址将相同.如果我这样做:
the contents can be different afterwards, since all mutateArray
needs is the address of an array to change its contents. However, the address of o
will be the same. If I do:
String x = "foo";
tryToMutateString(x);
x
的地址此后再次相同.由于字符串是不可变的,因此这意味着它仍将是"foo"
.
the address of x
is again the same afterwards. Since strings are immutable, this implies that it will also still be "foo"
.
对对象进行变异就是更改其内容(例如,成功更改 o
的最后一个元素,或尝试将"foo"的最后一个字母更改为"d").这不应与在调用者堆栈中重新分配 x
或 o
(不可能)相混淆.
To mutate an object is to change the contents of it (e.g. successfully changing the last element of o
, or trying to change the last letter of "foo" to 'd'). This should not be be confused with reassigning x
or o
in the caller's stack (impossible).
通过共享进行通话的维基百科部分可能会引起更多关注.
The Wikipedia section on call by sharing may shed additional light.