The terms "pass-by-value" and "pass-by-reference" have special, precisely defined meanings in computer science. These meanings differ from the intuition many people have when first hearing the terms. Much of the confusion in this discussion seems to come from this fact.

The terms "pass-by-value" and "pass-by-reference" are talking about variables. Pass-by-value means that the value of a variable is passed to a function/method. Pass-by-reference means that a reference to that variable is passed to the function. The latter gives the function a way to change the contents of the variable.

By those definitions, Java is always pass-by-value. Unfortunately, when we deal with variables holding objects we are really dealing with object-handles called references which are passed-by-value as well. This terminology and semantics easily confuse many beginners.

It goes like this:

public static void main(String[] args) {
    Dog aDog = new Dog("Max");
    Dog oldDog = aDog;

    // we pass the object to foo
    foo(aDog);
    // aDog variable is still pointing to the "Max" dog when foo(...) returns
    aDog.getName().equals("Max"); // true
    aDog.getName().equals("Fifi"); // false
    aDog == oldDog; // true
}

public static void foo(Dog d) {
    d.getName().equals("Max"); // true
    // change d inside of foo() to point to a new Dog instance construct red with name member variable set to "Fifi"
    d = new Dog("Fifi");
    d.getName().equals("Fifi"); // true
}

In this example, aDog.getName() will still return "Max". The value aDog within main is not changed in the function foo by creating new Dog with name member variable set to "Fifi" because the object reference is passed by value. If the object reference was passed by reference, then the aDog.getName() in main would return "Fifi" after the call to foo.

Likewise:

public static void main(String[] args) {
    Dog aDog = new Dog("Max");
    Dog oldDog = aDog;

    foo(aDog);
    // when foo(...) returns, the name of the dog has been changed to "Fifi"
    aDog.getName().equals("Fifi"); // true
    // but it is still the same dog:
    aDog == oldDog; // true
}

public static void foo(Dog d) {
    d.getName().equals("Max"); // true
    // this changes the name of d to be "Fifi"
    d.setName("Fifi");
}

In this example, Fifi is dog’s name after call to foo(aDog) because the object's name was set inside of foo(...). Any operations that foo performs on d are such that, for all practical purposes, they are performed on aDog, but it is not possible to change the value of the variable aDog itself.

For more information on pass by reference and pass by value, consult the following answer: https://stackoverflow.com/a/430958/6005228. This explains more thoroughly the semantics and history behind the two and also explains why Java and many other modern languages appear to do both in certain cases.

Top answer
1 of 16
7154

The terms "pass-by-value" and "pass-by-reference" have special, precisely defined meanings in computer science. These meanings differ from the intuition many people have when first hearing the terms. Much of the confusion in this discussion seems to come from this fact.

The terms "pass-by-value" and "pass-by-reference" are talking about variables. Pass-by-value means that the value of a variable is passed to a function/method. Pass-by-reference means that a reference to that variable is passed to the function. The latter gives the function a way to change the contents of the variable.

By those definitions, Java is always pass-by-value. Unfortunately, when we deal with variables holding objects we are really dealing with object-handles called references which are passed-by-value as well. This terminology and semantics easily confuse many beginners.

It goes like this:

public static void main(String[] args) {
    Dog aDog = new Dog("Max");
    Dog oldDog = aDog;

    // we pass the object to foo
    foo(aDog);
    // aDog variable is still pointing to the "Max" dog when foo(...) returns
    aDog.getName().equals("Max"); // true
    aDog.getName().equals("Fifi"); // false
    aDog == oldDog; // true
}

public static void foo(Dog d) {
    d.getName().equals("Max"); // true
    // change d inside of foo() to point to a new Dog instance construct red with name member variable set to "Fifi"
    d = new Dog("Fifi");
    d.getName().equals("Fifi"); // true
}

In this example, aDog.getName() will still return "Max". The value aDog within main is not changed in the function foo by creating new Dog with name member variable set to "Fifi" because the object reference is passed by value. If the object reference was passed by reference, then the aDog.getName() in main would return "Fifi" after the call to foo.

Likewise:

public static void main(String[] args) {
    Dog aDog = new Dog("Max");
    Dog oldDog = aDog;

    foo(aDog);
    // when foo(...) returns, the name of the dog has been changed to "Fifi"
    aDog.getName().equals("Fifi"); // true
    // but it is still the same dog:
    aDog == oldDog; // true
}

public static void foo(Dog d) {
    d.getName().equals("Max"); // true
    // this changes the name of d to be "Fifi"
    d.setName("Fifi");
}

In this example, Fifi is dog’s name after call to foo(aDog) because the object's name was set inside of foo(...). Any operations that foo performs on d are such that, for all practical purposes, they are performed on aDog, but it is not possible to change the value of the variable aDog itself.

For more information on pass by reference and pass by value, consult the following answer: https://stackoverflow.com/a/430958/6005228. This explains more thoroughly the semantics and history behind the two and also explains why Java and many other modern languages appear to do both in certain cases.

2 of 16
3628

I'm the author of the blog post you're talking about. To clarify a few things:

The Java Spec says that everything in Java is pass-by-value. There is no such thing as "pass-by-reference" in Java.

The key to understanding this is that something like

Dog myDog;

is not a Dog; it's actually a pointer to a Dog. The use of the term "reference" in Java is very misleading and is what causes most of the confusion here. What they call "references" act/feel more like what we'd call "pointers" in most other languages.

What that means, is when you have

Dog myDog = new Dog("Rover");
foo(myDog);

you're essentially passing the address of the created Dog object to the foo method.

(I say essentially because Java pointers/references aren't direct addresses, but it's easiest to think of them that way.)

Suppose the Dog object resides at memory address 42. This means we pass 42 to the method.

if the Method were defined as

public void foo(Dog someDog) {
    someDog.setName("Max");     // AAA
    someDog = new Dog("Fifi");  // BBB
    someDog.setName("Rowlf");   // CCC
}

let's look at what's happening.

  • the parameter someDog is set to the value 42
  • at line "AAA"
    • someDog is followed to the Dog it points to (the Dog object at address 42)
    • that Dog (the one at address 42) is asked to change his name to Max
  • at line "BBB"
    • a new Dog is created. Let's say he's at address 74
    • we assign the parameter someDog to 74
  • at line "CCC"
    • someDog is followed to the Dog it points to (the Dog object at address 74)
    • that Dog (the one at address 74) is asked to change his name to Rowlf
  • then, we return

Now let's think about what happens outside the method:

Did myDog change?

There's the key.

Keeping in mind that myDog is a pointer, and not an actual Dog, the answer is NO. myDog still has the value 42; it's still pointing to the original Dog (but note that because of line "AAA", its name is now "Max" - still the same Dog; myDog's value has not changed.)

It's perfectly valid to follow an address and change what's at the end of it; that does not change the variable, however.

Java works exactly like C. You can assign a pointer, pass the pointer to a method, follow the pointer in the method and change the data that was pointed to. However, the caller will not see any changes you make to where that pointer points. (In a language with pass-by-reference semantics, the method function can change the pointer and the caller will see that change.)

In C++, Ada, Pascal and other languages that support pass-by-reference, you can actually change the variable that was passed.

If Java had pass-by-reference semantics, the foo method we defined above would have changed where myDog was pointing when it assigned someDog on line BBB.

Think of reference parameters as being aliases for the variable passed in. When that alias is assigned, so is the variable that was passed in.

A discussion in the comments warrants some clarification...

In C, you can write

void swap(int *x, int *y) {
    int t = *x;
    *x = *y;
    *y = t;
}

int x = 1;
int y = 2;
swap(&x, &y);

This is not a special case in C. Both languages use pass-by-value semantics. Here the call site is creating additional data structure to assist the function to access and manipulate data.

The function is being passed pointers to data, and follows those pointers to access and modify that data.

A similar approach in Java, where the caller sets up assisting structure, might be:

void swap(int[] x, int[] y) {
    int temp = x[0];
    x[0] = y[0];
    y[0] = temp;
}

int[] x = {1};
int[] y = {2};
swap(x, y);

(or if you wanted both examples to demonstrate features the other language doesn't have, create a mutable IntWrapper class to use in place of the arrays)

In these cases, both C and Java are simulating pass-by-reference. They're still both passing values (pointers to ints or arrays), and following those pointers inside the called function to manipulate the data.

Pass-by-reference is all about the function declaration/definition, and how it handles its parameters. Reference semantics apply to every call to that function, and the call site only needs to pass variables, no additional data structure.

These simulations require the call site and the function to cooperate. No doubt it's useful, but it's still pass-by-value.

Discussions

reason: why java is not pass by reference? - Stack Overflow
Java is strictly pass by value..I am still confused with this concept. I have gone through many websites to get an answer for this but I am not able to find any good reason. Is there any proper rea... More on stackoverflow.com
🌐 stackoverflow.com
Can someone explain pass by value in Java please?
This is my favorite question about java. Its nearly impossible to answer easily because people mean different things. The real answer is Java passes by value, 100% of the time, but the value it passes for objects is the reference address of the object, not the object itself. This doesn't usually answer the question though, because what people are usually really asking is "If i pass an object to a method and perform an operation on it, will the change be evident in the original object once I exit the method?" Here's the (actual useful) breakdown: If you pass a primitive to a method, you get its value, and changing it will not change the value of the primitive you passed in. If you pass an object to a method, you get a reference (like a pointer) back to your original object. If you perform a method ON the object ( myObject.doSomething() ), the action that method takes WILL be performed on your original passed in object. This works LIKE pass by reference in other languages. If you perform an ASSIGNMENT on the object (anything with myObject = ...) then you are NOT affecting the original passed in object, you are just discarding your reference to it and replacing it with a new reference to a different object. Any operations you perform on the object after you have reassigned its reference in the method will NOT affect the passed in object, because those operations will be performed on the new object you assigned to the reference, not the original passed in reference. More on reddit.com
🌐 r/java
40
10
January 26, 2012
Why doesn't java support pass by reference like C++ - Stack Overflow
I have tried searching in Google why doesn't java support pass by reference , but I only get java does not support pass by reference and I couldn't find any reason behind it. Why can't you pass primitive datatype by reference ? Edit : Most of the people have closed my question assuming that it is ... More on stackoverflow.com
🌐 stackoverflow.com
Java is NEVER pass-by-reference, right?...right? - Stack Overflow
According to everything I've read about Java's behavior for passing variables, complex objects or not, this code should do exactly nothing. So um...am I missing something here? Is there some subtlety that was lost on me, or does this code belong on thedailywtf? ... Mehrdad: Just use Integer rather than int. ... Wrapping (in Integer or an array) isn't creating pass-by-reference ... More on stackoverflow.com
🌐 stackoverflow.com
🌐
DigitalOcean
digitalocean.com › community › tutorials › java-is-pass-by-value-and-not-pass-by-reference
Java is Pass by Value, Not Pass by Reference | DigitalOcean
December 6, 2022 - So, java refers the objects by their memory address. The name used to refer that memory location (i.e value) is termed as reference variable. As we are passing the reference of the memory location, java is pass by value (of the memory address of the object) but not pass by reference.
🌐
Quora
quora.com › Why-doesnt-Java-allow-you-to-pass-by-reference
Why doesn't Java allow you to pass by reference? - Quora
Answer (1 of 7): Because it is a “simplification” — keeping to the C model, rather than the C++ model. People who say things like “references are passed by reference, primitives are passed by value” are confused.
🌐
GeeksforGeeks
geeksforgeeks.org › java › g-fact-31-java-is-strictly-pass-by-value
Java is Strictly Pass by Value! - GeeksforGeeks
April 2, 2024 - Like C/C++, Java creates a copy of the variable being passed in the method and then do the manipulations. Hence the change is not reflected in the main method. ... In Java, all primitives like int, char, etc are similar to C/C++, but all ...
🌐
Sentry
sentry.io › sentry answers › java › is java pass-by-reference or pass-by-value?
Is Java Pass-By-Reference or Pass-By-Value? | Sentry
July 12, 2022 - Then the contents attribute of both Mug objects change to "Nothing". Functionally, this is similar to passing myMug by reference. However, the key difference is that we have two copies of the reference type value on the stack. Modern programming languages, such as Java, rarely use a true pass-by-reference system.
Find elsewhere
🌐
Reddit
reddit.com › r/java › can someone explain pass by value in java please?
r/java on Reddit: Can someone explain pass by value in Java please?
January 26, 2012 -

I've read multiple explanations online but I'm still having trouble understanding. I understand that Java is pass by value but from what I understand objects are passed by reference. My programming teacher even had trouble explaining this. Can someone please give me a clear explanation of this, in layman's terms, as if I had never programmed before?

Also, if someone could give some of the pros and cons of pass by value and pass by reference that would be great too, and what languages are pass by value and which are pass by reference?

Top answer
1 of 5
22
This is my favorite question about java. Its nearly impossible to answer easily because people mean different things. The real answer is Java passes by value, 100% of the time, but the value it passes for objects is the reference address of the object, not the object itself. This doesn't usually answer the question though, because what people are usually really asking is "If i pass an object to a method and perform an operation on it, will the change be evident in the original object once I exit the method?" Here's the (actual useful) breakdown: If you pass a primitive to a method, you get its value, and changing it will not change the value of the primitive you passed in. If you pass an object to a method, you get a reference (like a pointer) back to your original object. If you perform a method ON the object ( myObject.doSomething() ), the action that method takes WILL be performed on your original passed in object. This works LIKE pass by reference in other languages. If you perform an ASSIGNMENT on the object (anything with myObject = ...) then you are NOT affecting the original passed in object, you are just discarding your reference to it and replacing it with a new reference to a different object. Any operations you perform on the object after you have reassigned its reference in the method will NOT affect the passed in object, because those operations will be performed on the new object you assigned to the reference, not the original passed in reference.
2 of 5
14
http://stackoverflow.com/questions/40480/is-java-pass-by-reference
Top answer
1 of 2
15

By design:

Some people will say incorrectly that objects are passed "by reference." In programming language design, the term pass by reference properly means that when an argument is passed to a function, the invoked function gets a reference to the original value, not a copy of its value. If the function modifies its parameter, the value in the calling code will be changed because the argument and parameter use the same slot in memory.... The Java programming language does not pass objects by reference; it passes object references by value. Because two copies of the same reference refer to the same actual object, changes made through one reference variable are visible through the other. There is exactly one parameter passing mode -- pass by value -- and that helps keep things simple. -- James Gosling, et al., The Java Programming Language, 4th Edition

As for deeper reasons, here's my take: it's the combination of two facts:

  1. The last line of the Gosling citation: "...that helps keep things simple..."
  2. Unlike C++, Java is garbage collected with all objects allocated on the heap.

I can't help it if you don't like the first one. You'll have to tell James Gosling and Bill Joy and all the other folks who designed Java that they made a critical error. Good luck with that. Java is far more widely used than C++ today by several measures. The marketplace, however imperfect, has not penalized Java for what you perceive as an oversight.

Pass by value in C++ places burdens on both the developer (e.g. requirement of assignment and copy constructors) and the compiler writer (e.g. differentiating between stack and heap variables, all permutations of pass by value and reference with const and non-const).

The second one might have more of a technical explanation besides the designers' taste. I'm not an expert in the design and implementation of garbage collected systems, but perhaps that influenced their choice for a technical reason that I don't know.

2 of 2
6

My understanding is that the reason for not having pass-by-reference is mostly for security reasons: passing things by reference would enable a function to change stuff that is outside its scope and that means that my object (reference) may be replaced if I call a malicious function.

To elaborate: In Java, encapsulation is important and a safety measure. When giving a (pointer) to an object to a function that someone else wrote, I (as the caller) should be convinced that the function I call can only do with that object what I allowed it to do (using public members). Allowing a PBR would leave me (as the caller) in an unknown state after the function finished as I would not know if I am handling my own object or something else...

Top answer
1 of 2
9

Java is pass by value. Think of it like a pointer language like C, the value of the pointer (memory address) is being passed, so you have a reference to the same object. Primitives aren't stored internally the same way as Objects, so when you pass a primitive's value, it's the content, not a pointer.

2 of 2
7

There is a test for whether a language is pass-by-reference: can you write a swap function, such that after swap(a,b), the caller finds that the values of a and b are reversed? You cannot do this in Java, not even for objects.

Note that you cannot achieve this goal by swapping the internals of the two objects - while the data may change, the identity of the objects has not, and this has consequences. For one thing, any other variable in the program that referenced either object would also see the change.

To see why you cannot write this swap, consider a simplified model of the language, in which the value of a reference variable is the address of the object it is currently bound to (garbage collection complicates this picture in a way not relevant here.) Before the call to swap, the caller's stack frame has a slot for a, containing the address of object A, and a slot for b containing the address of B. When swap is called, it receives the values of a and b, which are the addresses of A and B respectively. Therefore, it is decoupled from the caller: there is simply no way for it to find the addresses of the slots for a and b within the caller's stack frame, and therefore no way to set them so that the caller will see them swapped.

@supercat suggests an alternative way of looking at it: conceptually, a reference variable holds the unique ID of the object it references, something that is fixed for the life of the object, and it is this that gets copied to the function in a call. This view also makes it clear that the function has no way to find, let alone modify, the variable in the caller's stack frame.

Call-by-reference means exactly the opposite, by definition: the function accesses its arguments through the caller's variable bindings, so that changing one of its arguments' binding in the function necessarily changes it in the caller's stack frame. The term dates to a time when mainstream languages did not have objects or references as first-class entities, and when an argument was passed, either a copy of its value (in pass-by-value) or its address (in pass-by-reference) was pushed on to the stack so that the function could retrieve it. Passing an argument's address allows swap to work, but passing an address it contains does not.

Another way of looking at it: pass-by-reference does not mean pass the reference held in the argument variable, it means create, in the function, a local variable that references the argument variable.

Therefore, we can see that Java uses pass-by-value, not pass-by-reference.

See also Java is Pass-by-Value, Dammit! which also discusses argument-passing in Java RMI.

🌐
Baeldung
baeldung.com › home › java › core java › pass-by-value as a parameter passing mechanism in java
Pass-By-Value as a Parameter Passing Mechanism in Java | Baeldung
January 8, 2024 - However, for a reference b1, we have assigned a new object. So it’s now pointing to a new object in heap memory. Any change made to b1 will not reflect anything in the original object: In this article, we looked at how parameter passing is handled in case of Primitives and Non-Primitives. We learned that parameter passing in Java is always Pass-by-Value.
Top answer
1 of 7
6

I've encountered experienced C and C++ developers who are convinced that Java is pass-by-reference for objects. One example I've used is this one:

void changeInt(int x){
  x = 42;
}

void changeString(String x){
  x = "hello world";
}

void testChanges(){
  int i = 0;
  changeInt(i);
  System.out.println(i); // still 0

  String s = "test";
  changeString(s);
  System.out.println(s); //still test
}

The changeInt() function fails to change the value of the parameter, because it's pass-by-value. But then the changeString() function also fails to change the value of the parameter- because it's also pass-by-value.

I also really like Cup Size -- a story about variables and its follow-up Pass-by-Value Please to explain the difference between pass-by-value and pass-by-reference from a Java perspective.

Now, as for whether you actually bring this up to your teacher, I'm not sure. If I were you I'd probably just bite my tongue and move on with my life.

2 of 7
5

In an introductory Java class, I think it's fine to say that primitives are passed by value and that objects are passed by reference. That tells students what they need to know, although I might phrase it differently. (I'd say that primitives and references are copied when they're passed.)

In an upper-division programming languages course, I'd go into more detail about calling conventions and the full story about pass-by-value and pass-by-reference (and pass-by-name, so I can tell the joke about Niklaus Wirth), if there's time.

While I love for students to catch my mistakes and white lies, I think it might be nitpicky to do so in this case. If you feel a need to bring it up, go to the professor's office hours and express confusion reconciling what he said with what you've read online (perhaps citing a specific source). If he's a decent professor, he'll admit to having oversimplified or he'll accept the new knowledge.

Update

After reading Kevin Workman's answer, I see the problem with using the term "call by reference". I agree that no good can come from misusing that term. My second and third paragraphs still stand.

🌐
InfoWorld
infoworld.com › home › blogs › java challengers
Does Java pass by reference or pass by value? | InfoWorld
June 6, 2024 - The reason is that Java object variables are simply references that point to real objects in the memory heap. Therefore, even though Java passes parameters to methods by value, if the variable points to an object reference, the real object will ...
🌐
Medium
medium.com › javarevisited › is-java-pass-by-reference-or-pass-by-value-f03562367446
Is Java ‘pass-by-reference’ or ‘pass-by-value’? | by Pravinkumar Singh | Javarevisited | Medium
July 15, 2023 - The original object is modified in the method, resulting in the change being reflected in the output. However, it's crucial to understand that the object's reference itself is passed by value, meaning the object's memory address cannot be changed. Java is a pass-by-value language in both cases — primitive data types as well as objects.
🌐
Blogger
javarevisited.blogspot.com › 2012 › 12 › does-java-pass-by-value-or-pass-by-reference.html
Is Java Pass by Value or Pass by Reference? Example
December 7, 2022 - Java is always pass by value, because it doesn't support pointer, which is essential for pass by reference. Confusion arises while passing object to a method, since Java pass handle to that object, programmer think that as reference or pointer, ...
🌐
Software Testing Help
softwaretestinghelp.com › home › java tutorial for beginners: 100+ hands-on java video tutorials › java pass by reference and pass by value with examples
Java Pass By Reference And Pass By Value With Examples
April 1, 2025 - Q #4) Explain why there is no call by reference in Java. Answer: Call by reference needs the memory location to be passed and these memory locations further require pointers which Java does not have.
🌐
Medium
medium.com › javarevisited › is-java-pass-by-value-or-pass-by-reference-73a73b0c2234
Is Java “Pass by Value” or “Pass by Reference”? | by BaseCS101 | Javarevisited | Medium
February 4, 2024 - Actually, the copy of the variable is passed and not the variable itself. The copied reference variable in called function can change the Object’s state(fields) but cannot change the address held by the actual/original reference variable of the main function.
🌐
Reddit
reddit.com › r/learnjava › passing by reference vs passing by value in java question
r/learnjava on Reddit: Passing by reference vs passing by value in Java question
August 25, 2021 -

I've currently got a year of Java under my belt, but after coming back from summer break which I did not code at all whatsoever, my brain is foggy.

I remember in C++ we would use things like & for reference or * pointer. In Java I don't really ever remember worrying about reference vs value, but today our professor brought it up and I embarrassingly got it wrong. The explanation was something like that the other method creates a copy of the variable so updating that copy doesn't update the original variable.

Then he talked about primitive types have this issue but if you create some other variable it won't happen? (Might have incorrectly paraphrased that)

As I said I am not drop dead dumb, I just really need a refresher. I kind of remember using this keyword and getters/setters to properly update the program, but yeah I am super foggy right now...

Top answer
1 of 5
12
Variables hold values. In the case of a variable of a primitive type, the held thing is the value, like 2, ot 3.5, or 'd'. If the variable is of some object type, the value held is a reference, or location, or the actual object. When you call a method, the values in the arguments to the method, like add(x,y) are copied to the parameters of the method. If the method is defined like public static int add(int number1, int number2) and called like add(x,y), then the value in x is copied to number1 and the value in y is copied to number2. In the case of calling a method with an object, like count(numbers), where numbers might be an array, then the value stored in numbers, which is a reference to that array, is sent to the method. The parameter knows about the same numbers array as in the argument - the array is not copied, just the reference. This reference value in Java is actually closer to a C/C++ raw pointer than a reference type in C++. There is a layer of indirection that must be understood. Drawing pictures helps.
2 of 5
5
Java is only pass by value. If you want to mimic pass by reference, I'd change the input type to a Producer of that type. For example, let's say you have Baz foo(Bar b) { /// } and you wanted to make that pass by reference, I'd change it to Baz foo(Producer b) { /// } which has a similar effect. Scala, which also runs on the JVM, has support for actual pass-by-reference: //pass by value def foo(b: Bar): Baz = ??? // pass by ref def foo(b: => Bar): Baz = ??? which I imagine does the same thing under the hood.
🌐
Codeline24
codeline24.com › home › understanding java: pass by value vs. pass by reference
Java Pass by Value vs. by Reference
May 18, 2024 - This sheds light to Pass by reference vs. by value dilemma and avoid confusion, as it might appear that objects are passed by reference. However, in reality, Java strictly passes references by value.