You are confused because your analogy is not right. In Java, there is no such thing as an "argument object", because "objects" themselves are not values in Java (there are no "object types" in Java). The only types in Java are primitive types and reference types, where "references" are pointers to objects. So in Java you can only have pointers to objects as the value of a variable or parameter, and you only deal with objects through pointers to objects.
"you cannot change where that pointer points" is a consequence of pass-by-value. Java is always pass-by-value, which means assignment to the parameter cannot change the value of a passed variable. Remember that variables can only be of primitive type or reference type. Here you are talking about reference type. So the "value" of a variable of reference type is the reference (pointer to object), i.e. the address of the object it points to. Hence, you cannot change the value means you cannot change where the pointer points.
For example, in Java you might have something like this:
public static void reassign(String a) {
a = new String("efgh");
}
public static void main(String[] args) {
String x = "abcd";
System.out.printf("x is %s at %x\n", x, System.identityHashCode(x)); // x is abcd at 25154f
reassign(x);
System.out.printf("x is %s at %x\n", x, System.identityHashCode(x)); // x is abcd at 25154f
}
Here, x
in main
is a pointer to an object. a
in reassign
is also a pointer to an object. Assigning to the pointer parameter a
in reassign
has no effect on the passed pointer variable x
(i.e. it does not affect where the pointer points to) because it's pass-by-value.
The equivalent of the above code in C++ would be like this:
void reassign(string *a) {
a = new string("efgh");
}
int main() {
string *x = new string("abcd");
cout << "x is " << *x <<" at " << x << endl; // x is abcd at 0x82b1008
reassign(x);
cout << "x is " << *x <<" at " << x << endl; // x is abcd at 0x82b1008
return 0;
}
In addition to the pass-by-value shown above, C++ also has pass-by-reference, where assignment to a parameter has the same effect as assigning to the passed variable in the calling scope. Here is the exact same thing as above but with pass-by-reference:
void reassign(string *&a) {
a = new string("efgh");
}
int main() {
string *x = new string("abcd");
cout << "x is " << *x <<" at " << x << endl; // x is abcd at 0x8673008
reassign(x);
cout << "x is " << *x <<" at " << x << endl; // x is efgh at 0x8673030
return 0;
}
Note that in none of the cases here did we change the object pointed to. We simply created a new object and tried to change the pointer to point to this object. The old object is still unchanged. The ability to change an object is an independent and orthogonal issue from pass-by-value and pass-by-reference, so we do not go into it here.