5

I used to think Java supports both pass by value and passby reference but i came accross many discussions like

  1. Java is always pass by value, with no exceptions, ever .
  2. Java is always pass-by-value
  3. Java always passes arguments by value NOT by reference.
  4. Java passes references by value.So you can't change the reference that gets passed in.

If java only supports pass by value
how does java.util.Array.sort() or Collections.sort(unsortList) work?

int iArr[] = {2, 1, 9, 6, 4};// sorting array

Arrays.sort(iArr);    

System.out.println("The sorted int array is:");
for (int number : iArr) {
    System.out.println("Number = " + number);
}

Update: What passing a reference (by value) Actually mean? How does it differ from passing by reference behaviour of Arrays in C or C++?

Update: Please correct me if I am wrong. In C we pass the address of variables when passing by reference.In Java we pass the reference to the object (or value).As long as the variable in the method is pointing to the Object the value of the object changes with the varible in the method invoked. Java Pass by reference There is no copy of Object or reference made!, I could see only 2 different variables pointing to the same Object as in pass by reference.Similar in C++ pass by reference two different variables points to the same address.

Community
  • 1
  • 1
Jishnu Prathap
  • 1,955
  • 2
  • 21
  • 37
  • 5
    I'm voting to close this question because the linked answers in the question already answer the question. – Chetan Kinger May 22 '15 at 09:43
  • kindly Point me to the answer please. – Jishnu Prathap May 22 '15 at 09:46
  • 1
    The top three answers to [this](http://stackoverflow.com/questions/40480/is-java-pass-by-reference-or-pass-by-value/40523#40523) question. – Chetan Kinger May 22 '15 at 09:51
  • it doesnt explain the 2nd part of my qtn. – Jishnu Prathap May 22 '15 at 10:07
  • 1
    It explains the second part of your question with detailed examples. What did you not understand from it? – Chetan Kinger May 22 '15 at 10:17
  • Unlike aioobe's commnet It doesnt explain why passing a reference (by value) Actually differ from passing by reference .It doesnt explain how Arrays.sort(iArr) changes the value of iArr . I have spent time understanding the answers i pointed to in my question . – Jishnu Prathap May 22 '15 at 10:31
  • 1
    Quoting from the the top rated answer from [this](http://stackoverflow.com/questions/40480/is-java-pass-by-reference-or-pass-by-value/40523#40523) answer `If it were passed by reference, then the aDog.getName() in main would return "Fifi" after the call to foo`. This explains how pass by value differs from pass by reference. Quoting from the second top-rated answer: `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")`. Kindly explain what did you not understand from the answers? They answer whatever you asked. – Chetan Kinger May 22 '15 at 10:41
  • @chetan You are missing the whole point !! the scenarios are different In the top voted answer he explains how it is pass by value showing the dog.getName() doesnt change after setting it. In this scenario the value actually changes.The arrays passed to a function behaves similar to the pass-by-reference in c or C++ except that you cant swap them(u can change the value).As explained by aioobe ,This is due to the fact that in java we are passing the reference by value. Setting it to Null doesnt affect the actual variable .this is not properly explained in the answer u have pointed out. – Jishnu Prathap May 22 '15 at 11:01
  • You said `In this scenario the value actually changes` : So does it in this scenario explained in the linked answers : `but note that because of line "AAA", its name is now "Max"`. You said `Setting it to Null doesnt affect the actual variable`. This is exactly what the linked answers also explain : `In this example aDog.getName() will still return "Max". The value aDog within main is not overwritten in the function foo with the Dog "Fifi"`. The linked answers are synonymous to [spoon feeding](http://english.stackexchange.com/questions/29672/is-spoon-feeding-a-widely-accepted-usage) – Chetan Kinger May 22 '15 at 11:39
  • 2
    I understand your question very well. No matter how you put it, java is pass by value and if you understand what that means, you will never have to ask any question related to how references work in Java. – Chetan Kinger May 25 '15 at 12:39
  • The linked questions, plus the knowledge that arrays are reference types, should make this question unnecessary. – cHao May 26 '15 at 12:16
  • Related: [What exactly does "pass by reference" mean?](http://stackoverflow.com/q/8113781/319403). I personally think [my answer](http://stackoverflow.com/a/16702757/319403) explains it pretty clearly. – cHao May 26 '15 at 12:27

4 Answers4

13

Arrays are reference types, so the iArr variable holds a reference to an array.

In other words, when you call

Arrays.sort(iArr);

you're passing a reference (by value) to the sort method, which sorts the array that iArr refers to.


From comments:

What does passing a reference (by value) actually mean?

What pass by reference means is that you're basically passing the variable itself to the method. I.e., what ever the method does with the variable affects the variable on the outside. This is never the case in Java. (Try implementing a swap method and you'll see what I mean.) Passing by value means that you pass the value that's stored in the variable. In this case the value is a reference, so it's passing a reference by value.


Re. second update:

Judging from your image, I think you've understood the situation very well, and I think it boils down to terminology.

If we forget about C++ for a while, it's really simple. All you need to keep in mind is that (A) when you invoke method(var) the argument is a copy of whatever var contains, and (B) the content of a non-primitive variable is a reference (a "pointer" if you so like).

Note that in your question you have

int iArr[] = {2, 1, 9, 6, 4};

which is equivalent to

int[] iArr = new int[] { 2, 1, 9, 6, 4 };

so it all checks out: iArr holds a reference and new returns a reference.

When you invoke Arrays.sort(iArr) the content of iArr is passed (i.e. the reference to the array). This is still not pass-by-reference because the value is passed, not the variable itself. If you reassign the formal parameter inside the method to point to some other array, iArr will still point to the original array when the method returns.

If we do think in terms of C++ things tend to be a bit more complicated; C++ notion of reference is slightly different. With a C++ reference you can in fact implement a real swap:

void swap(int &x, int &y)
{
   int temp = x;
   x = y;
   y = temp;
}

I.e. you can pass in "a variable" (as opposed to just the content of a variable). I like to think of this as you're sharing the scope of the variable with the method you're calling. This can't be done in Java.

So with that in mind, I'd say Java reference are much more like C++ pointers, except that they are limited in the sense that you can't dereference using * operator as you can in C++ (you can't do *person in Java, even though person stores what corresponds to a pointer to a person) and you can't get the address of an object using & operator. Also you can't do any pointer arithmetic. You can't for instance do iArr + 3 to get to the fourth element of your array.

aioobe
  • 413,195
  • 112
  • 811
  • 826
  • What passing a reference (by value) Actually mean? How does it differ from passing by reference behaviour of Arrays in C or C++? – Jishnu Prathap May 22 '15 at 09:37
  • 3
    What *pass by reference* means is that you're basically passing *the variable* to the method. I.e., what ever the method does with the variable affects the variable on the outside. This is not the case in Java. (Try implementing a `swap` method and you'll see what I mean.) Passing by value means that you pass the *value that's stored* in the variable. In this case the value is a reference, so it's passing a reference by value. – aioobe May 22 '15 at 09:41
  • 1
    in support with @aioobe comment, check this [Why can't you swap in Java?](http://www.javaworld.com/article/2077424/learn-java/does-java-pass-by-reference-or-pass-by-value.html) – TSKSwamy May 22 '15 at 09:53
  • @JishnuPrathap, you're welcome. I don't think any answer is satisfactory among the questions you linked to, but it's impossible to post a new answer that get near the top at this point. – aioobe May 22 '15 at 09:58
  • @aioobe plz add your explanation in coment to ur answr it will be more helpful to future users. – Jishnu Prathap May 22 '15 at 10:29
  • @JishnuPrathap, what do you think of my updated answer? I'm curious if the C++ related explanation or the non-C++ related explanation appeals to you best. – aioobe May 26 '15 at 11:55
  • Similar to passing the copy of reference to the parameters in java – Jishnu Prathap May 26 '15 at 12:05
  • 1
    [Yes](http://stackoverflow.com/questions/3954764/how-is-reference-implemented-internally) (but C++ references are still more powerful since internally the compiler will use `*` or that pointer, which can't be done in Java). – aioobe May 26 '15 at 12:07
4

Java always uses pass by value. Pass by value means the 'value' is copied when it's passed. When it comes to passing objects the 'value' that gets copied is the 'reference' to the object, not the object it self. Therefore if you were to make changes to the object inside a method, those would get reflected after method execution. However setting the passed 'reference' to 'null' for example would have no effect.

Dev Blanked
  • 8,555
  • 3
  • 26
  • 32
  • I'd upvote if it wasn't for *"When it comes to passing objects..."* because objects aren't passed to begin with. If you update, please reply so I get a ping. – aioobe May 26 '15 at 12:01
2

Java supports pass by value only.Its doesn't supports pass by reference.

See the below Code:

 public static void main(String[] args) {
List l1 = new ArrayList(Arrays.asList(4,6,7,8));
System.out.println("Printing list before method calling:"+ l1);
foo(l1);
System.out.println("Printing list after method calling:"+l1);
}

public static void foo(List l2) {
l2.add("done"); // adding elements to l2 not l1
l2.add("blah");
}

It looks like pass by reference. But internally works as by value only.

Output:

Printing list before method calling:[4, 6, 7, 8]
Printing list after method calling:[4, 6, 7, 8, done, blah]

This example is almost similar to your post. You are passing array to Arrays method like Arrays.sort(iArr). I am passing list parameters to my method foo ie: foo(list1).

See the post for more information

Java pass by reference issue with List

Community
  • 1
  • 1
  • *"Even though we are passing by reference internally..."* No, we're not, and saying we are is just confusing matters. – T.J. Crowder Jul 17 '16 at 18:35
2

Java is always pass by value. But passing parameter value depends on type of entity you are passing..

Primitives - The original value is passed. So changes done in the called method wont affect the original value in calling method.

Objects - The memory address(i.e. location in the heap memory) referring the object is passed. So changes done in the called method reflects in calling method.

Bhargav Kumar R
  • 2,190
  • 3
  • 22
  • 38
  • By saying *"But passing parameter value depends on type of entity you are passing.."* you're just adding to the confusion! There is no difference. In both cases *The original value is passed. So changes done in the called method wont affect the original value in calling method.* It's boils down to explaining that the "original value" of `iArr` is a reference to something on the heap. Whatever the method does, it can't change the content of `iArr`. – aioobe May 26 '15 at 12:04