0

Why is it, that when I add an object, to my ArrayList, which Should be passing it a Reference to the object, then I make the object equal to null, it outputs perfectly fine.

    ArrayList<Test> testList = new ArrayList<>();

    Test test = new Test();
    System.out.println(test);

    testList.add(test);

    for(Test t : testList)
    {
        System.out.println(t);
    }

    test = null;

    for(Test t : testList)
    {
        System.out.println(t);
    }

The test constructor goes as:

int x = 0;

Test()
{
    x = 50;
}

public String toString()
{
    return x + "";
}

Yet, the output is 50, 50, 50 instead of 50, 50, null

Otanan
  • 459
  • 3
  • 12
  • 1
    Java is pass-by-value – Pshemo Feb 19 '14 at 18:42
  • Elaborate please? @Pshemo – Otanan Feb 19 '14 at 18:43
  • When you do `testList.add(test);` you are passing value of `test` (currently stored instance, not `test` reference). If you later change value of `test` (in your case to `null`) it can't affect value passed earlier. More info at [is-java-pass-by-reference](http://stackoverflow.com/questions/40480/is-java-pass-by-reference) – Pshemo Feb 19 '14 at 18:44
  • 1
    @Pshemo I sort of view it as: java only passes by reference (pointers to the values). The values exist in the memory and are there if there is a reference to the value. Methods on the reference affect the value, but assigning the reference to another value just points the reference away. Is this a reasonable interpretation? – Justin Feb 19 '14 at 18:52
  • @Quincunx I see it as: method`s argument is just local copies of passed reference (it copies value of original reference - original object, or as other prefer to say objects memory address). So later if original reference will change, copy will remain the same and will contain original value. – Pshemo Feb 19 '14 at 19:03

3 Answers3

3

When you call add, the ArrayList now has its own reference to the same object.

test ----> Test() object
             ^
testList ----|

That is unaffected by setting your reference test to null.

test ----> null

testList ----> Test() object
rgettman
  • 176,041
  • 30
  • 275
  • 357
2

Because there is a difference between Reference Types and Value Types in Java.

You add a reference to the value (a.k.a. an object) to the list, then you delete the reference. However the value is still there in memory, and the list still has a reference to that value, despite your original reference being nullified

Omar Himada
  • 2,540
  • 1
  • 14
  • 31
1

When you are passing reference to object to ArrayList you actually create yet another reference that is used by ArrayList to refer to the object.

When you assign null to variable test you actually "cancel" your reference. Nothing happens with reference of array list.

Even simpler.

If you have 2 variables: one and two:

Test one = new Test()
Test two = one;

At this point both references point to the same object.

one = null;

Now one is null, but two still refers to that object.

AlexR
  • 114,158
  • 16
  • 130
  • 208