The key to understanding this is to remember that all objects are accessed indirectly via a reference. When an object is passed as an argument the method, the "value" actually being passed is a reference, and not the object itself.
When you null out the l
parameter in the update
method, you are setting that specific reference to null
- the original reference m
remains unchanged, and the object referred to by both references is also unchanged.
If you know C/C++, then this can be paraphrased as:
void update(List* l)
{
l = NULL; // set the pointer to null - the object (*list) is unmodified
}
void main()
{
List* m = ...;
update(m);
printf(m->values());
}
The pointer m
is copied by value. The object pointed to (the list *m) is not altered in any way. The value of the pointer is copied from m
to l
. When l
is set to NULL, that is a local change that only affects the value of the l
pointer.
Here's an example where pass by reference involves a non-local change,
class NonLocalChange
{
public void change(int[] i) {
i[0] = 2;
i = null;
}
public static void main(String[] s) {
int[] m = new int[1];
m[1] = 3;
change(m);
System.out.println(i[0]);
}
}
The result printed is 2
. This is because the change
method changes the object referenced by l
, and not just the reference itself.
Note that this doesn't throw a NullPointerException, even though l is assigned to null. As before, it's a reference, and so it's a local assignment to the value of that reference.