英文:
Copy of variable in for-each loop?
问题
我有这样的印象,for-each循环中的变量会获取从数组中的元素复制的值。例如:
String[] strs = new String[] {"a", "b"};
for (String s : strs) {
s = "c";
}
for (String s : strs) {
System.out.println(s);
}
上述代码与原始数组strs无关,因此输出仍然是:
a
b
这是预期的,因为for-each循环中的变量s实际上是元素的副本。然而,如果我定义了自己的类并带有赋值构造函数,行为就会改变:
class Node {
public Node(Integer value, String str) {
value_ = new Integer(value.intValue());
str_ = new String(str.toCharArray());
}
public Node(Node node) {
this(node.value(), node.str());
}
public Integer value() { return value_; }
public String str() { return str_; }
public Integer value_ = 0;
public String str_ = "null";
}
Node[] my_list = new Node[] {new Node(1, "a"), new Node(2, "b")};
for (Node n : my_list) {
n.value_ = 3;
n.str_ = "c";
}
for (Node n : my_list) {
System.out.println(n.value() + " " + n.str());
}
现在的输出是:
3 c
3 c
这意味着for-each循环中的变量n不是元素的副本,而是一个引用。
有人可以帮忙解释一下为什么对于String和我自己的类Node,for-each循环的行为是不一致的吗?
谢谢!
英文:
I'm under the impression that the variable in for-each loop would get the value copied from the elements from the array. E.g.:
String[] strs = new String[] {"a", "b"};
for (String s : strs) {
s = "c";
}
for (String s : strs) {
System.out.println(s);
}
The above code has nothing to do with the original array strs and thus the output is still:
a
b
This is expected as the variable s in the for-each loop is actually a copy of the element. However, if I define my own class along with assignment constructor, the behavior changes:
class Node {
public Node(Integer value, String str) {
value_ = new Integer(value.intValue());
str_ = new String(str.toCharArray());
}
public Node(Node node) {
this(node.value(), node.str());
}
public Integer value() { return value_; }
public String str() { return str_; }
public Integer value_ = 0;
public String str_ = "null";
}
Node[] my_list = new Node[] {new Node(1, "a"), new Node(2, "b")};
for (Node n : my_list) {
n.value_ = 3;
n.str_ = "c";
}
for (Node n : my_list) {
System.out.println(n.value() + " " + n.str());
}
The output now is:
3 c
3 c
which means the variable n in the for-each loop is not a copy of the element but a reference.
Anyone can help explains why the behavior of for-each loop on String and my own class Node is inconsistent?
Thanks!
答案1
得分: 0
在 for-each 循环中,变量的值是你正在迭代的值的副本。
请记住,Java 有两种类型的值:基本值和引用值。引用值是指向对象的 指针。
在第一个示例中,s = "c"
使变量 s
指向一个新对象。由于 s
是循环内的局部变量,外部无法观察到任何影响。
在第二个示例中,n.value_ = 3
首先找到 n
所指向的对象:请记住,n
是引用值,它是指向对象的指针。然后它会更改该对象内部字段 value_
的值。这些对象存在于循环外部,因此可以从外部看到此更改。
另请参阅关于引用值与基本值语义如何影响传递给方法的值的非常相似的讨论,位于 https://stackoverflow.com/questions/40480/is-java-pass-by-reference-or-pass-by-value。
英文:
The value of the variable in the for-each loop is a copy of the values you are iterating on.
Remember that Java has two types of values: primitive values and reference values. Reference values are pointers to objects.
In the first example, s = "c"
makes the variable s
point to a new object. Since s
is a local variable within the loop, there is no effect you can observe from the outside.
In the second example, n.value_ = 3
first finds the object that n
points to: remember that n
is a reference value, it's a pointer to an object. Then it goes and changes the value of field value_
within that object. These objects exist outside of the loop, so this change can be seen from the outside.
See also the very similar discussion on how the reference vs value semantics affect values passed to methods at https://stackoverflow.com/questions/40480/is-java-pass-by-reference-or-pass-by-value
答案2
得分: 0
在第一个示例中,正如你所指出的,你正在遍历 str 数组,然后将值设置为 c。然而,你并没有将值 3 设置给 str 数组。你可以通过对第一个示例进行以下更改来将值设置为 c。
for (int i = 0; i < strs.length; i++) {
strs[i] = "c";
}
这实际上是在更改 str 数组的值。
然而,在第二个示例中,你正在对传递给循环的对象的变量进行更改。因此,对象内部的变量发生了变化(实际上,你将值设置给了对象的变量)。
英文:
In the first example, as you rightly pointed out, you are iterating through the str array and then setting the value to c. You are however not setting the value 3 to the str array. You can set the value to c by making the below changes to your first example.
`for (int i = 0;i<strs.length;i++) {
strs[i] = "c";
}`
This in effect is changing the value of the str array.
However in the second example you are making changes to the variables of the object passed in the for loop. Therefore the variables inside the object changed (in effect, you set the value to the objects variable)
专注分享java语言的经验与见解,让所有开发者获益!
评论