3

Possible Duplicate:
Is Java pass-by-reference?
Java pass by reference

For the following Java program, my understanding is that a is a reference type to an Integer, like pointer type in C/C++. So any changes done in method f to its value will be reflected after the method returns. But println still prints its original value 0 instead of 3.

Integer and int does not make a difference. Was my previous understanding wrong? Please help. Thank you!

  public static void f(Integer b){
            b=3;
        }
        public static void main(String[] args){
            Integer a=0;
            f(a);
            System.out.println(a);
      }
1
  • It is the same, I tried. Commented May 29, 2012 at 23:46

6 Answers 6

4

Java always passes arguments by value NOT by reference.


Let me explain this through an example:

public class Main
{
     public static void main(String[] args)
     {
          Foo f = new Foo("f");
          changeReference(f); // It won't change the reference!
          modifyReference(f); // It will modify the object that the reference variable "f" refers to!
     }
     public static void changeReference(Foo a)
     {
          Foo b = new Foo("b");
          a = b;
     }
     public static void modifyReference(Foo c)
     {
          c.setAttribute("c");
     }
}

I will explain this in steps:

  1. Declaring a reference named f of type Foo and assign it to a new object of type Foo with an attribute "f".

    Foo f = new Foo("f");
    

    enter image description here

  2. From the method side, a reference of type Foo with a name a is declared and it's initially assigned to null.

    public static void changeReference(Foo a)
    

    enter image description here

  3. As you call the method changeReference, the reference a will be assigned to the object which is passed as an argument.

    changeReference(f);
    

    enter image description here

  4. Declaring a reference named b of type Foo and assign it to a new object of type Foo with an attribute "b".

    Foo b = new Foo("b");
    

    enter image description here

  5. a = b is re-assigning the reference a NOT f to the object whose its attribute is "b".

    enter image description here


  6. As you call modifyReference(Foo c) method, a reference c is created and assigned to the object with attribute "f".

    enter image description here

  7. c.setAttribute("c"); will change the attribute of the object that reference c points to it, and it's same object that reference f points to it.

    enter image description here

I hope you understand now how passing objects as arguments works in Java :)

Sign up to request clarification or add additional context in comments.

3 Comments

+1 for the cool graphics
Did you do all those drawing in 10 minutes or had them already?
@Luciano I had them already: stackoverflow.com/a/9404727/597657
2

Integer (like other "basic" classes) are inmutable objects. It means that there is no method by which you can change the value. If you do

 new Integer(1);

the object created will always hold the 1 value.

Of course you can do

Integer a = new Integer(1);
a = new Integer(2);

but here what you are doing is creating two objects, and assigning a to each of them in turn.

When calling the method, you are passing a copy of the reference in a (as edalorzo said), so you are doing pretty much the same (but without changing the original a reference).

Of course, lots of classes are not inmutable. In these classes, you would have one (or several) methods that allow you to change the object inner state, and (as long as you are accessing the same object) these changes would be "shared" by all the references of the object (since they all point to the same one). For example, suppose Integer had a setValue(int) method, then

public static void f(Integer b){      
        b.setValue(3);      
    }      
    public static void main(String[] args){      
        Integer a=0;      
        f(a);      
        System.out.println(a);      
  }    

Would work as you expected.

Comments

2

The method receives a copy of the reference. The assignment doesn't change the value that the integer represents (it couldn't even if it wanted to - Integer is immutable in Java). It is just setting b to point at something else. The original Integer object that a is pointing to is unaffected by this change.

Before b = 3;

------    ------
|  a |    |  b |
------    ------
  |          |
  ------------
        |
   Integer(0)

After b = 3;

------    ------
|  a |    |  b |
------    ------
  |          |
  |          |
  |          |
Integer(0)  Integer(3)

If you wanted to change the value you'd have to use a mutable type instead.

Related

Comments

1

Integer is immutable so the passing by reference won't work as expected. see Java : Best way to pass int by reference

2 Comments

So how does immutable references differ from mutable ones?
@littleEinstein: It's not the reference that is mutable or immutable. It's the type. Integer is immutable. You can't change the contents of an Integer once you have created it. But you can reassign a variable to point to a new Integer with a different value.
0

In Java everything is pass-by-copy, in your method you are chaining the reference, not the actual object it is pointing to.

3 Comments

Then how do I make changes to the int and persists the effect after the method returns in Java? Do I have to package the int to a class?
Make your method return the new integer and assigned to the original reference that you passed as argument to your method.
Downvoter, please, enlighten me.
0

Your understanding was right but Integers are immutable. If you want to affect the value of a Integer variable, the only way is to create a new Integer object and discard the old one. For this reason, the statement b=3 has no effect.

Comments