And who has the authority to decide?
Edit: Apparently I haven\'t succeeded in formulating my question well.
I am not asking how Java\'s
Passing by reference is, in effect, passing a reference to a value -- rather than a copy of it -- as an argument.
I guess before we go on, certain things should be defined. I may be using them differently than you're used to seeing them used.
An object is a molecule of data. It occupies storage, and may contain other objects, but has its own identity and may be referred to and used as a single unit.
A reference is an alias, or handle, to an object. At the language level, a reference mostly acts like the thing it's referring to; depending on the language, the compiler/interpreter/runtime/gnomes will automagically dereference it when the actual object is needed.
A value is the result of evaluating an expression. It is a concrete object, that can be stored, passed to functions, etc. (OOP wonks, note i use "object" here in the generic "molecule of data" sense, rather than the OOP "instance of a class" sense.)
A variable is a named reference to a pre-allocated value.
Especially note: variables are not values. The name notwithstanding, variables typically do not change. Their value is what changes. That they're so easily mixed up is partly a testament to how good the reference<-->referent illusion usually is.
A reference-typed variable (a la Java, C#, ...) is a variable whose value is a reference.
Most languages, when you pass a variable as an argument, will by default create a copy of the variable's value and pass the copy. The callee binds its name for the parameter to that copy. This is called "passing by value" (or, more clearly, "passing by copy"). The two variables on either side of the call end up with different storage locations, and are thus completely different variables (only related in that they typically start out with equal values).
Passing by reference, on the other hand, doesn't do the copy. Instead, it passes the variable itself (minus the name). That is, it passes a reference to the very same value the variable aliases. (This is typically done by implicitly passing a pointer to the variable's storage, but that's just an implementation detail; the caller and callee don't have to know or care how it happens.) The callee binds its parameter's name to that location. The end result is that both sides use the same storage location (just by possibly different names). Any changes the callee makes to its variable are thus also made to the caller's variable. For example, in the case of object-oriented languages, the variable can be assigned a whole different value.
Most languages (including Java) do not support this natively. Oh, they like to say they do...but that's because people who have never been able to truly pass by reference, often don't grok the subtle difference between doing so and passing a reference by value. Where the confusion comes in with those languages, is with reference-type variables. Java itself never works directly with reference-type objects, but with references to those objects. The difference is in the variables "containing" said objects. The value of a reference-type variable is such a reference (or, sometimes, a special reference value that means "nothing"). When Java passes such a reference, while it doesn't copy the object, it still copies the value (ie: the reference the function gets is a copy of the value the variable refers to). That is, it is passing a reference, but is passing it by value. This allows most of the things that passing by reference allows, but not all.
The most obvious test i can think of for real pass-by-reference support, would be the "swap test". A language that natively supports passing by reference must provide enough support to write a function swap that swaps the values of its arguments. Code equivalent to this:
swap (x, y): <-- these should be declared as "reference to T"
temp = x
x = y
y = temp
--
value1 = (any valid T)
value2 = (any other valid T)
a = value1
b = value2
swap(a, b)
assert (a == value2 and b == value1)
(Obviously, languages that don't have mutable variables can't be tested this way -- but that's fine, because they don't matter. The big semantic difference between the two is how modifiable the caller's variable is by the callee. When the variable's value is not modifiable in any case, the difference becomes merely an implementation detail or optimization.)
Note, most of the talk in this answer is about "variables". A number of languages, like C++, also allow passing anonymous values by reference. The mechanism is the same; the value takes up storage, and the reference is an alias to it. It just doesn't necessarily have a name in the caller.