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.

  • 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 – Encaitar Mar 21 '14 at 22:18
  • 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
  • 2
    @Encaitar: That's pretty funny, since Java bears very little resemblance to Lisp. – Robert Harvey Mar 21 '14 at 23:23
  • 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 2:38
  • 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 4: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).

  • 1
    The 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. – user7043 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 0:27
  • 1
    The Java community seems to have settled on "pass by value" 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" and "call by sharing". – user7043 Mar 23 '14 at 12:25
  • 1
    Java 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

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