0

why is the following code output equals 0?

public class A{


    public static void main(String [] args){

        int a=0;
        foo(a);
        System.out.println(a);
    }

    public static void foo(int a){
        a=78;
    }


}
mary
  • 869
  • 5
  • 13
  • 26

6 Answers6

5

It outputs 0 because that's the value of a in the main function. Java is entirely pass-by-value, it doesn't have pass-by-reference at all. So when you call foo, the value of the a variable is passed into foo, not a reference to the a variable. foo then modifies the value of its a argument, but that has no effect whatsoever on the a variable in main.

You may hear people talk about "pass-references-by-value" or "pass-by-value-of-reference," which can be confusing and I strongly recommend avoiding that terminology like the plague. :-) But here's what they're talking about:

In your example, a is a primitive. The a variable contains the value 0. But equally, you could do this:

 Object a = new Object();
 foo(a);

What gets passed to foo now? Exactly the same thing that was passed when it was an int: The value of a. The only difference is that now, the value of a is an object reference. Object references are just values like anything else; they tell the JVM where the data for the object is in memory. Think of them like indexes into a big array or something.

So where:

int a = 42;

gives us this in memory:

+---------+
|    a    |
+---------+
|   42    |
+---------+

this

Object a = new Object();

...gives us this:

+---------+
|    a    |             
+---------+             +-----------------+
| mumble  |------------>| The object data |
+---------+             +-----------------+

It's important to understand that a still just contains a value, just like when it contains an int or a float. It's just the meaning of that value which differs, just as the meaning of the value held by an int is different from the meaning of a value held by a float. In the case of an object reference, the meaning of the value is "the object is over there".

Just like you can have more than one variable holding the value 42, you can have more than one variable holding a reference to the same object:

int a, b;
a = 42;
b = a;

gives us

+---------+     +---------+
|    a    |     |    b    |
+---------+     +---------+
|   42    |     |   42    |
+---------+     +---------+

and so similarly

Object a, b;
a = new Object();
b = a;

gives us

+----------+     +----------+
|     a    |     |     b    |
+----------+     +----------+
|  mumble  |--+--|  mumble  |
+----------+  |  +----------+
              |
              |
              |    +-----------------+
              +--->| The object data |
                   +-----------------+

a and b still just contain values, like 42; but that value tells the JVM where the object is, and so they refer to (point to) the same object.

Getting back to foo, when you call a function, passing in an argument is exactly like assigning a variable to another variable, so think of b above as the foo function argument.

In the comments below, you've asked about arrays. Arrays are just like objects — or they are objects; choose your preferred semantics. :-) So:

int[] a;
int[] b;

a = new int[5];
b = a;

gives us:

+----------+     +----------+
|     a    |     |     b    |
+----------+     +----------+
|  mumble  |--+--|  mumble  |
+----------+  |  +----------+
              |
              |
              |    +----------------+
              +--->| The array data |
                   +----------------|
                   | [0]: 0         |
                   | [1]: 0         |
                   | [2]: 0         |
                   | [3]: 0         |
                   | [4]: 0         |
                   +----------------+

So consider:

public static final void main(String[] args) {
    int[] a = new int[5];
    foo(a);
    System.out.println(a[0]);
}

void foo(int[] b) {
    b[0] = 42;
}

That prints 42. Why? Because the value of a was passed into foo, and so b within foo points to the same array that a points to. You can change the state of the object using the reference. Note that you're not changing the value of b, you're changing the state of the thing that b refers to.

Contrast with:

public static final void main(String[] args) {
    int[] a = new int[5];
    foo(a);
    System.out.println(a[0]);
}

void foo(int[] b) {
    b = new int[5]; // <==== change here
    b[0] = 42;
}

Now it prints 0, because you've assigned a new value (a new object reference) to b, which has no effect on the value held by a or the thing that a's value refers to.

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • ...I'm not sure I'd say that without qualification, i.e. "pass-references-by-value." – Louis Wasserman Feb 16 '12 at 10:10
  • @LouisWasserman: The OP didn't mention object references, and I find they muddy the discussion because they think the word "reference" relates to pass-by-reference, which it doesn't. – T.J. Crowder Feb 16 '12 at 10:10
  • @T.J.Crowder, well the title explicitely mentions "pass by reference". – A.H. Feb 16 '12 at 10:13
  • 1
    I hesitate to make sweeping generalizations like "_entirely_ pass-by-value" when that seems likely to further confuse the OP in the not-too-distant future. http://stackoverflow.com/a/40523/869736 manages to make the distinction very nicely clear, though. – Louis Wasserman Feb 16 '12 at 10:15
  • @A.H.: Yes, and pass-by-reference has **nothing** to do with object references. – T.J. Crowder Feb 16 '12 at 10:20
  • wait a second. but If I try to pass an Object meaning not a simple type then It's passed by reference? – mary Feb 16 '12 at 10:21
  • @T.J.Crowder: Regading mary's last comment: And here we are. Is there _anyone_ who does _not_ saw this coming upfront? – A.H. Feb 16 '12 at 10:23
  • and how do I do the swap function in java? why is it when I pass an array and I edit it's inside then it does change the contents? – mary Feb 16 '12 at 10:23
  • Upvoted for the _very_ thorough explanation, but I feel like there must be some answer we can just bookmark and link for anyone who asks this question. – Louis Wasserman Feb 16 '12 at 10:28
  • @mary: No, the object reference is passed by value, and so both the original variable and the argument *refer to* the same object. That's not pass-by-refernce. See my updated answer. Your array example is an object reference being passed by value. Since the argument in the function has a copy of the object reference, it can change the object's state (including the entries in the array). – T.J. Crowder Feb 16 '12 at 10:28
  • Bleahhhhhhh. @A.H., I concede. I still think there should be One True Link for this, but that probably still wouldn't work. Maybe http://javadude.com/articles/passbyvalue.htm ? – Louis Wasserman Feb 16 '12 at 10:38
  • @LouisWasserman: I completely agree about the One True link. Surely there has to be a previous, clear, correct answer on this? :-) – T.J. Crowder Feb 16 '12 at 10:42
  • @JohanSjöberg: Yeah, I went looking and found that too. Didn't think this was *quite* a duplicate of that, but the explanations there are good and we should highlight it for the OP. (Done) – T.J. Crowder Feb 16 '12 at 11:15
3

Because Java is strictly "Pass by value". And note carefully: Passing a reference by value is not the same as "Pass by Reference".

A.H.
  • 63,967
  • 15
  • 92
  • 126
1

Arguments in Java are always passed by value. Argument a in foo is not connected with vaiable a in main.

zvez
  • 818
  • 5
  • 8
1

Ya. Because java is all pass by value and i is a primitive type so the one that passed is his value which is 0 not his reference.

You can read the link below to easily understand how parameter are passed in java

http://www.javaranch.com/campfire/StoryPassBy.jsp

Bryan Giovanny
  • 424
  • 2
  • 7
1

When you are calling foo(a) inside main() method, it takes the value of a declared inside main() method and passes it to the argument of foo() method.

The argument of foo() will always act as local scoped variable to foo() method. So whatever you did inside it will never reflect inside main() method. So when you print it, it shows the value of a which was declared inside main() method locally.

Chandra Sekhar
  • 18,914
  • 16
  • 84
  • 125
1

Java uses pass-by-value, not pass-by-reference. The confusion a lot of people suffer from is that if you're dealing with an Object (int is NOT an Object) then the value is actually a reference to the Object.

The following would work:

public class A{
    public static void main(String [] args){
        IntWrapper a = new IntWrapper(0);
        bar(a); // Pass a copy of the reference to a
        System.out.println(a.intValue);
    }

    public static void bar(IntWrapper iw) { // iw is a reference because IntWrapper is an Object
        iw.intValue = 78;
    }

    class IntWrapper { // Classes implicitly extend Object
        int intValue;

        IntWrapper(int value) {
            intValue = value;
    }
}
vaughandroid
  • 4,315
  • 1
  • 27
  • 33