Definitive source for Java
As the comments already indicated, there is but one official specification for the Java language, namely the Java Language Specification made available from Oracle.
The answer to your particular question of the calling behavior is found in section 8.4.1:
When the method or constructor is invoked (§15.12), the values of the actual argument expressions initialize newly created parameter variables
Source of the confusion
Note, however, that the folks who write the JLS may not share the same definition of terms as others. In particular, the discussion whether Java is call-by-value or something else typically stems from looking at other definitions.
Call-by-value is typically defined as passing a copy of the argument to the function. This behavior is most exposed in C++ where you have an actual choice of whether you want call-by-value or call-by-reference per argument and for call-by-value you even have things like copy-constructors.
This general idea, that call-by-reference allows you to change the original object, whereas call-by-value leaves it untouched is kind of pointless in Java though (at least if you ignore primitive types). Unlike the C-family of languages, Java has no concept of a pointer to some object, so every single variable is like a pointer to some object instead. This gives the appearance to people familiar with C, that Java does in fact always pass around references (after all, if you pass an object into a function, you do not know if that function changes the internal attributes of the object).
You can argue against this argument by accepting the notion of pointers, which in turn means, that a function call is still using call-by-value, because it simply creates a copy of that pointer, which will end up pointing to the same object again.
What is most confusing is that passing an object to a method in Java will never create a full (deep!?) copy of that object - despite the fact that Java is call-by-value. Other languages (like C++) call their function calling semantics call-by-value as well, but in those languages the actual semantics differ.
Code examples
Assume you have the following two methods in your class:
private void f(C c) {
c.setSomething();
c = new C();
c.setSomething2();
}
private void g(final C c) {
c.setSomething();
}
Now on the call-site you find something like this:
C myC = // get some C instance
f(myC); // passes the value
The f
method would now change the attributes of the myC
object, because it works on exactly the same instance. In contrast, the variable c
can be assigned a different instance, such that the call to setSomething2
will not affect the instance myC
is referring to.
If you swap f
for g
on the call-site, a typical rookie-mistake from C/C++ programmers that became Java programmers is to assume that final
does somehow ensure your object is not modified. Of course, the above code still works and modifies the object though. What does no longer work due to final
is merely, that the variable c
is re-assigned to a different C
instance within that method.
This behavior also tricks more experienced Java developers. While few forget that a final List<C>
argument is allowed to modify the list, not so few run into bugs, after having written a method that returns a List<C>
(be it final or not, as that does not make any relevant difference) and being bitten by usage-site code that modifies it.