Is there any specific reason they decided to go with Call by value? Is it for simplicity?
3 Answers
The terms "Call by Value" and "Call By Reference" are sometimes used a bit loosely by programmers, and the use of those terms doesn't always reflect the underlying reality.
When you hear someone refer to Call By Value and Call By Reference, what they are usually saying is that primitive values are Call By Value, whereas objects are Call By Reference. You can tell the difference, in part, because when you pass a parameter by value, you always get the original value back. In other words, when you Call by Value, your function is getting a copy of the primitive, not the actual primitive.*
Call by Reference is different. When you Call by Reference, the object you are passing can be modified by the function, and the object will retain those changes when the function returns. Java works like this; objects passed to a function retain changes made to the objects by the function.
So why isn't Java Call by Reference, then?
Because, when you pass an object to the parameter list of a function, you're not actually passing the object by reference. What you are actually doing is passing the reference to the object, by value.
I know this may seem like splitting hairs, but think about it. Does Java create a copy of the object before it passes it to you, like it does with primitives? No; it creates a copy of the reference, and passes that to the function. Can you modify the reference to point to a different object, and expect that change to be retained when the function returns? No, you can't.
* If a variable containing a primitive is passed as a function parameter, the value of the variable is passed, not the actual variable. If a mathematical expression is passed to the function, the expression is evaluated first, and the result is passed to the function by value.

- 198,589
- 55
- 464
- 673
Java is heavily influenced by Objective-C. Objective-C is heavily influenced by Smalltalk. Smalltalk is heavily influenced by Lisp. All of those are call-by-value.
Or, more, specifically, it is call-by-object-sharing (aka call-by-sharing or call-by-object), which is a special case of call-by-value, where the value is a pointer to a (potentially mutable) object.
For primitives, Java actually uses call-by-value without a pointer, however, since primitives are immutable, you cannot tell the difference anyway. (You can only observe the difference when you have two pointers to a mutable object and mutations performed by following one pointer can be observed by following another pointer, but primitives aren't mutable.)
So, to answer your question: history and heritage.

- 101,921
- 24
- 218
- 318
-
1"We were after the C++ programmers. We managed to drag a lot of them about halfway to Lisp." - Guy Steele, co-author of the Java spec from [PG](http://www.paulgraham.com/icad.html) – Encaitar Mar 21 '14 at 22:18
-
1In what sense of the word are primitives immutable? `int x = 1; x = 2;` works, doesn't it? – Mar 21 '14 at 23:11
-
2@delnan: You haven't mutated `1`. You have reassigned `x`. `1` doesn't become `2`, `x` becomes `2`. Variables are indeed mutable (unless they are `final`). – Jörg W Mittag Mar 21 '14 at 23:22
-
3@Encaitar: That's pretty funny, since Java bears very little resemblance to Lisp. – Robert Harvey Mar 21 '14 at 23:23
-
1@JörgWMittag `x` is not a reference to an int object. It **is** an `int`, but it is not *the* number 1. `x = 1` meant "copy the value 1 into `x`", not "make `x` refer to 1". There are thirty two bits somewhere in computer memory, they used to be 00...001 and now they're 00...010 - sounds like mutation to me. Expecting mutation of the concept of the number one would be a bit silly, wouldn't it? (Though I've heard anecdotes of the very first FORTRAN compilers allowing such fun.) – Mar 21 '14 at 23:29
-
@RobertHarvey But it's a lot closer than C++. As in Lisp, Java has no concept of memory or memory management, it only has values/objects. As in Lisp, everything's a reference type (with the ugly exception of primitives, a concession to performance). – Mar 21 '14 at 23:33
-
1@delnan: There is a *fundamental* difference between "mutating the value a variable holds" and "making the variable hold a different value". And it goes to the very heart of the fundamental distinction between variables and values. Basically, you are saying that there is no difference between a variable and a value. But there is: `1` is a value of type `int`. `x` is not an `int`, it's a *variable* that can *hold* a value of type `int`. You can make `x` hold a different value, but you can not make the same value different. Unlike, say, a `StringBuilder`, where you *can* mutate the value. – Jörg W Mittag Mar 22 '14 at 02:38
-
@JörgWMittag: Don't laugh. I used one of those Fortran compilers. – david.pfx Mar 22 '14 at 03:05
-
@delnan: Maybe this will help? https://gist.github.com/JoergWMittag/9700582 – Jörg W Mittag Mar 22 '14 at 03:48
-
@JörgWMittag It appears you are using a very different, less common (and IMHO less useful) definition of "value". When I say "the value 1" I don't refer to some platonic mathematical entity; I mean any part of memory that equals the constant `1`. That includes variables of type `int`, because (unlike with reference types such as your `MutableInt`) the variable actually holds that value, not a reference to a value elsewhere. In other words, `x` is as much of an `int` value as `y` in `MutableInt` is a reference. Which brings me to the gist, which only illustrates that `int` is a *value type*... – Mar 22 '14 at 11:37
-
1@JörgWMittag ... I do agree that variables and values are distinct entities (clearly `1` is not a variable). But I consider variables of value type *values*. As far as I can tell, this is a standard view, and it does not appear to lead to any faulty conclusions. And thus, when I say "`int` is mutable", I do not claim that all values of type `int` can be changed, I claim that *some* such values (namely those that are variables, fields, array slots, etc. and not `final`) can be changed, by replacing them with a copy of another value. – Mar 22 '14 at 11:44
-
1@delnan: I agree with Jörg and believe you are the one using a different (and less common and useful definition). Variables are mutable in most languages, including Java, and in those languages saying that you are "mutating" a value is limited to structures that can have part of their structure changed. In this view, ints are not made of a series of bits, they are whole, distinct values ie 1 or 2, not whatever bit pattern is used to hold a specific number. And in java mutable structures have to be classes.References aka pointers, refer to locations in memory and changing that memory is CBR. – jmoreno Mar 23 '14 at 04:56
Java has call by value for a small number of predefined value types, and call by reference for object types. [The reference is internally a pointer that is passed by value, but that's not the point.]
In C# (which is kind of Java 3.0) there are out
and ref
parameters, but Java doesn't have them. As a compiler writer I can tell you that they really complicate things. You have to decide whether to use a pointer mechanism (similar to objects) which leads to boxing; whether to use copy-in-copy-out which leads to aliasing problems; how to track whether variables are initialised or not. I guess the Java designers thought this was all too hard, or just not worth it.
The real decision made by Java was not to treat value types as first class citizens. There are no user-defined value types, no boxing and only pass by value. In C# they were thought worthwhile, but in Java they thought primitive values and user-defined objects were enough. I prefer C#, but I almost never use out
or ref
parameters.
Edit: In my defence, call by reference has been used to describe a range of strategies since the 1960s, and my usage here is borderline and will offend purists. I use it in the sense that the object is not copied, but any change to the passed in object will affect the original. However, an assignment to the passed in parameter will not affect the original but instead refer to a new object (or null).

- 8,105
- 2
- 21
- 44
-
1The traditional, widely used, and IMHO far more useful definition of "pass by reference" has *nothing* to do with the things called references in Java, the former referring exclusively to things like C#'s `ref` and `out`. Saying that Java does pass by reference both ignores a much older definition of the term and confuses distinct concepts that unfortunately share a name. – Mar 22 '14 at 19:00
-
@deknan: I understand your point. See edit. Feel free to propose an alternative term. I don't know one. – david.pfx Mar 23 '14 at 00:27
-
1The Java community seems to have settled on "[pass by value](http://stackoverflow.com/q/40480/395760)" with the pre-emptive clarification that for classes, the value being passed is an object reference. There are some other languages with nigh-identical parameter passing strategy; some of those invent new terms. Two alternatives used in the Python ecosystem are "[call by object](http://effbot.org/zone/call-by-object.htm)" and "call by sharing". – Mar 23 '14 at 12:25
-
1Java is pass-by-value. Always. Sometimes the value is a pointer, sometimes not. Just like in C, which is also always pass-by-value. In C, it's easy to see, because you pass the pointer explicitly as a value. In Java, the pointer is implicitly passed, which confuses some people, but the mechanism is the same. Barbara Liskov coined the term "call-by-object-sharing" for exactly this special case of pass-by-value-where-the-value-is-a-pointer when describing the semantics of CLU (which are identical to Java, C# (by default), Python, Ruby, ECMAScript, PHP, Smalltalk, …). – Jörg W Mittag Mar 23 '14 at 12:46
-
@JörgWMittag: Your opinion, not mine, but ultimately just a matter of definitions, terminology, semantics. We all know the technology, but we're not going to agree what to call it. – david.pfx Mar 23 '14 at 13:04