5

This program gives 6 as output, but when I uncomment the line 9, output is 5. Why? I think b.a shouldn't change, should remain 5 in main.

1  class C1{
2      int a=5;

3      public static void main(String args[]){
4          C1 b=new C1();
5          m1(b);
6          System.out.println(b.a);
7      }

8      static void m1(C1 c){
9          //c=new C1();
10         c.a=6;
11    }
12 }
Aleks G
  • 56,435
  • 29
  • 168
  • 265
Naman
  • 2,363
  • 5
  • 26
  • 27
  • 10
    Java is *always* pass by value, but the value you are passing is the reference variable, so it *seems* to be pass by reference in this situation (but it's not). Edit, as @mprabhat states in his great answer (1+). Also I upvoted your question as I don't see why it was downvoted. Are we downvoting because folks aren't born knowing Java? – Hovercraft Full Of Eels Apr 24 '12 at 15:02
  • 1
    You should step through both versions of your code in a debugger and see the difference. – Matt Ball Apr 24 '12 at 15:02
  • 1
    //s.a http://stackoverflow.com/questions/40480/is-java-pass-by-reference – FailedDev Apr 24 '12 at 15:04

6 Answers6

10

When you pass object in Java they are passed as reference meaning object referenced by b in main method and c as argument in method m1, they both point to the same object, hence when you change the value to 6 it gets reflected in main method.

Now when you try to do c = new C1(); then you made c to point to a different object but b is still pointing to the object which you created in your main method hence the updated value 6 is not visible in main method and you get 5.

mprabhat
  • 20,107
  • 7
  • 46
  • 63
  • 3
    Here is a pretty good article that explains what @mprabhat is saying with pictures if that helps you. http://www.javaworld.com/javaworld/javaqa/2000-05/03-qa-0526-pass.html – Windle Apr 24 '12 at 15:11
  • Here I doubt, `Objects are passed by Reference`, this statement is completely wrong, IMHO in Java, instead `Object References are passed by Value`, I can give one wonderful example for this, though books say otherwise :-) +1, though for the rest of the part – nIcE cOw May 23 '12 at 03:44
3

You're passing to your method m1 a copy of a reference to an Object of type C1.

If you uncomment the line, you're taking that reference and pointing it somewhere else (not that the original reference is still pointing at the first object), so, when you print the value of b, you're printing the value of the original object, that you didn't change.

This question has some very good answers to it, and you should really give it a look.

Is Java "pass-by-reference" or "pass-by-value"?

Community
  • 1
  • 1
pcalcao
  • 15,789
  • 1
  • 44
  • 64
  • 1
    Thanks, I still think a bit in terms of pointers in my head (that's basically what they are in essence), but reference is the correct terminology. – pcalcao Apr 24 '12 at 15:06
3

Java is pass-by-value, in layman terms meaning that when you pass an argument you create a copy of the pointer variable. Object variables should really be read like pointers in C: this somehow makes things easier to understand, at least when coming from the C world (where C is pass-by-value only).

So when doing c=new C1(), or in general when performing any assignment to c, you are making c (which formerly pointed to the same location of memory that b pointed) point to another location. Hence the following c.a=6 is an assignment to a member of the object pointed by c, which is not the object pointed by b anymore.

Luca Geretti
  • 10,206
  • 7
  • 48
  • 58
1

this is because c in m1(C1 c) is a reference to an object, and when you do c.a=6 now a is equals to 6 in this object. But if you do c=new c1() inside this method, c now is referencing a completly new object, then you are doing c.a=6 in this new object. Afterthat, you go out of the method, and the other c object still has the value 5

Yotes
  • 378
  • 3
  • 16
1

Your method m1(b); is called in main, causing a new instance created in m1 to supercedes already created instance of C1 in main method. If you comment the instantiation in m1, the first instance in main then takes effect. This is because in java objects are passed by reference not by value.

Bitmap
  • 12,402
  • 16
  • 64
  • 91
1

In Java other than primitive types everything is pass by reference, though it says pass the copy of the reference.

Hence in your case in the first instance both of the pointers b and c points to the same object hence updated value is reflected back in the main method.

In second instance when you make c to point to a new object(by calling new) b is still pointing to the object created in main method hence updated value is not reflected in main method as b and c are pointing to two different objects.