-1

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!

  • That's because you didn't modify `n` in the last example. You modified a field in `n`. To make it the same as your string example, try `n = new Node( 3, "c" );` instead. – markspace Apr 09 '20 at 01:56

2 Answers2

0

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 Is Java "pass-by-reference" or "pass-by-value"?

Joni
  • 108,737
  • 14
  • 143
  • 193
0

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)

swithen colaco
  • 157
  • 1
  • 12