Roedy Green sez:
It says: "can change the fields in the caller's objects", so how is
that a pass by value?
Because what is being passed is not an object, but a *reference to
an object*, where "reference" is to be understood as "Java's nearest
analogy to pointer" rather than whatever is meant by "reference" in C++.
I don't care about the reference, I care about the object behind it.
The important part is that caller code can modify the object I've
passed to it, so the object is a "var" parameter.
The object is not a parameter at all.
One of the critical distinctions between Java and C++, at least
from the point of view of helping people coming to Java from C++
get acclimated, is this:
In C++, if you have a class MyClass, the line
MyClass obj;
declares a variable that's an instance of MyClass, and allocates
space (on the stack, usually?) for a MyClass object. If I remember
my C++ right, it also creates the object by calling the no-argument
constructor.
In Java, the same line declares *a reference to a MyClass object*.
The nearest C++ analog is
MyClass* obj;
No MyClass object is created until one writes something such as
obj = new MyClass();
IMO, it's sloppy terminology to talk about passing objects as
parameters to Java methods, because in Java you can't do that.
What you're doing is passing *references [ "pointers" ] to objects*.
It's analogous to passing, in C++, a pointer to an object.
In C++, if you pass, by value, a pointer to an object, both the caller
and the callee can change the value of the pointed-to object. That
doesn't make this pass by reference, because what's actually being
passed is a copy of a pointer; changing the callee's copy of the
pointer doesn't change the caller's copy. It's the same in Java.
So, C++ gives you two ways of referring to objects (directly and
through pointers), while Java only gives you one (through its
version of pointers, "references"). The Java syntax for referring
to objects by way of references to them unfortunately looks like
the C++ syntax for referring to objects directly.
I think a lot about Java makes more sense, coming from C++, if
you can make the following mental transformations:
Java:
MyClass obj;
obj = new MyClass();
obj.method();
obj.field = value;
C++ (apologies if I don't get this exactly right -- I'm a bit rusty):
MyClass *obj;
obj = new MyClass();
obj->method();
obj->field = value;
This "pass by reference versus pass by value" discussion is a hardy
perennial in these parts, as you may or may not know. Some C++
programmers don't seem very amenable to the argument that Java
passes everything by value (but you have to understand what's being
passed), so perhaps you won't find this convincing. My two cents'
worth, though.