Is there any specific reason they decided to go with Call by value? Is it for simplicity?
closed as primarily opinion-based by gbjbaanb, Martijn Pieters, gnat, Dynamic, Blrfl Mar 23 '14 at 10:35
Many good questions generate some degree of opinion based on expert experience, but answers to this question will tend to be almost entirely based on opinions, rather than facts, references, or specific expertise. If this question can be reworded to fit the rules in the help center, please edit the question.
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.
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.
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
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
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).