Search code examples
javaooplocalevariable-assignmentassignment-operator

Local usage of new keyword


I didn't expect that new doesn't change the instance variables if instance variables are already assigned.

Did I understand correctly?

class Foo {
    String name = "Java";
}
class Main {
    public static void main(String args[]) {
        Foo foos[] = { new Foo(), new Foo() };
        foos[0].name = "bar";
        for (Foo c : foos) c = new Foo();
        for (Foo c : foos) System.out.println(c.name);
        for (Foo c : foos) c.name = "baz";
        for (Foo c : foos) System.out.println(c.name);
    }
}

Output

bar
Java
baz
baz

In the above example, the new works more like casting the object to the same class is already it. What is the practical use for this behavior?


Solution

  • It is because Java is always pass-by-value. Variable c doesn't reflect the array element, but its reference value is copied. So at first, c points to the value of the array element, but when you reassign c using c = new Foo(), variable c will point to something else. For that reason, the array element itself is unaffected.

    1. In this code,

      for (Foo c : foos)
      

      the reference to the array element (for example foos[0]) is copied to c.

    2. But when you assign a new Foo instance to c, it is not reflected by the array, you simply have assigned something to c.

      c = new Foo();
      
    3. In the next loop iteration, the next element is reassigned to c, leaving the object you created by c = new Foo() loosely into memory. It will be garbage collected soon.

    I noticed that you're coming from a C world, which explains the confusion. But in Java, arguments passed to a method or the element reference in a foreach loop are always copied. This post explains further details about this behavior.