4

I know that Java is by default call-by-value but I am not sure where in the Java Language Specification this is addressed. Google searching only seems to find me unofficial sources but never points to where the actual part of the specification that describes this is.

Where in the JLS does it state that Java is call-by-value and how does that part of the specification actually say that it is call-by-value rather than some other convention?

  • 5
    For Java it's the JLS obviously. It is the official docs for Java. You'll find the necessary info in Ch 15 and Ch 8. – Ordous Nov 27 '14 at 14:17
  • okay I honestly dont know where Im supposed to look for the answer to this question lol. But thanks Ordous – Tim Atkinson Nov 27 '14 at 14:36
  • 2
    And for C and C++ it's ISO. This isn't asking for a recommendation (subjective) or favorite (subjective) off-site resource. This is asking for the official documentation, which happens to have 3 objective answers. Vote to reopen. – MSalters Nov 27 '14 at 16:02
  • @MSalters I've narrowed this down to just Java so that one can have an answer that exactly and completely answers this question (rather than having three overlapping answers). Asking about Java, and C++, and C can lead to having three overlapping answers, none of which completely answer the question. – user40980 Nov 27 '14 at 17:52
  • related (probably not a duplicate): Which arguments pass by value and which pass by reference in Java? – gnat Nov 27 '14 at 18:01
5

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.

  • 1
    "This gives the appearance to people familiar with C, that Java does in fact always pass around references" suggests to me that you're claiming that Java doesn't pass around references. In the language of Java's type system, the values that it passes are all either primitives of references. I'm not sure whether there's a different wording which is less likely to mislead people, though, because the problem is that different communities use the same word with different connotations. – Peter Taylor Nov 28 '14 at 17:32
1

Pass-by-value/pass-by-reference is a property of the semantics of the language. It's not up to someone to "specify" independently of the language specification; rather, it arises from how the semantics of the language work (which in the case of Java is specified in the JLS). If the language standard actually describes pass-by-value semantics, but the language creator "specifies" the language to be pass-by-reference, that does not make it pass-by-reference.

First, you have to agree on what pass-by-value/pass-by-reference means. The commonly-used definition is that if you do simple assignment (using =) to a parameter inside a function, and it has the same effect as simple assignment to the passed variable in the calling scope, it is pass-by-reference; if it has no effect in the calling scope, it is pass-by-value.

In Java, parameter variables are newly created variables for that method invocation, and initialized with copies of the passed value. Also, assignment in Java only alters that variable, and not possibly any other variable. These things combined fit the definition of pass-by-value.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.