Nothing is passed by reference in Java - but you need to know what the value of a variable is.
The value of a variable of type int[]
is not an array. It's a reference to an array. All arrays are reference types, even if it's an array of primitives.
When you write:
int[] x = { 1, 2, 3, 4, 5 };
someMethod(x);
then the value of x is passed by value to someMethod
. It's a reference to an array - the method can change the contents of the array, but it won't be able to change the value of x
itself, which it could do if Java used pass-by-reference.
Once you understand that the value of any expression is either a reference or a primitive value, a lot of things become clearer. For example, take this code:
int[] x = { 1, 2, 3, 4, 5 };
int[] y = x;
y[0] = 10;
System.out.println(x[0]);
What would you expect the result to be? The assignment operator copies the value from the RHS to the LHS - so x
and y
are references to the same array. Therefore the final line prints out 10. This "copying the value" is exactly the same principle used for argument passing.
There's no inconsistency here - you just need to understand what's going on, and what pass-by-value and pass-by-reference really mean.
EDIT: I'm really surprised there's still any doubt about this.
From the Java Language Specification, section 8.4.1 (Formal Parameters):
When the method or constructor is invoked (§15.12), the values of the actual argument expressions initialize newly created parameter variables, each of the declared Type, before execution of the body of the method or constructor
That's practically the definition of pass by value semantics: the values of the arguments are used as the initial values of the parameters.
Those values may be references or they may be primitive values - it doesn't change the fact that it's the value which is passed.
EDIT: The definition you use, while badly expressed in my view, certainly does not mean that claiming Java passes everything by value is misleading.
It says, for pass by value:
This makes a copy of the variable and
can be quite slow and inefficient if
the variable is large like an array.
Note that it was talking about C and C++ (although C++ does have pass by reference as well, in fact). It talks about making a copy of the variable. That's exactly what Java does. The difference is that in Java, the value of the variable is always either a primitive value or a reference. It's never an object.
Once you understand that crucial point (and it's important for more than just argument passing) it's entirely straightforward to correctly say that Java passes everything by value. When a method or constructor is invoked, the arguments are evaluated and the values are used as the initial values of the parameters. That's pass by value, and that's what Java does for all parameters.
As for the PDF you linked to - that's a shamefully poor discussion of the topic, IMO. It makes a mess of what pass by reference means, it special-cases String for no good reason (String happens to be immutable, but other classes can be too) and it's generally wrong. Would it help if I gave some links supporting my point of view?
There are hundreds more. You aren't the first one to be confused by this, but Java really does pass everything by value, even references.