1

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

hi i have developed following code.In swap method,i swap the references of two objects.then it will be changed in called method(here swap()) but not changed in main method..why?

class Check
{

    public void swap(PassByRefDemoMain obj1,PassByRefDemoMain obj2)
    {

        PassByRefDemoMain temp;
        temp=obj1;
        obj1=obj2;
        obj2=temp;
        System.out.println(obj1.id+ " "+ obj2.id);

    }
}


public class PassByRefDemoMain {
    int id;
    PassByRefDemoMain(int id)
    {
        this.id=id;
    }
public static void main(String[] args) {
        PassByRefDemoMain obj1=new PassByRefDemoMain(10);
        PassByRefDemoMain obj2=new PassByRefDemoMain(20);

        Check obj=new Check(); 
        obj.swap(obj1,obj2);

        System.out.println(obj1.id + " " + obj2.id);

    }

}
Community
  • 1
  • 1
Jayesh
  • 6,047
  • 13
  • 49
  • 81

3 Answers3

9

The objects you pass to the method are passed as references, meaning that changing their members will be seen outside, BUT the references themselves are passed by value, meaning that changing the references will not be seen by the caller. Here's an experiment:

class Person {
    public String name;
}

class Test {
    public static void changePerson(Person p) {
         p.name = "Tudor";
         p = null;
    }

    public static void main(String[] args) {
        Person p = new Person();
        p.name = "John";
        changePerson(p);
        System.out.println(p.name); // prints Tudor and you don't get NPE
    }
}
Tudor
  • 61,523
  • 12
  • 102
  • 142
7

Java is pass by value.

You have only two objects. When you call the swap method two new references are copied but they point to the same objects. In the method you just change where the copied references point. But the original references in the main method are untouched.

A - obj1
B - obj2

Acopy - obj1
Bcopy - obj2

After method:

Acopy - obj2
Bcopy - obj1

But A still points to obj1, and B still points to obj2.

Petar Minchev
  • 46,889
  • 11
  • 103
  • 119
  • but still i have confusion.you said all the changes will be affected to copy of refernces,not original object references.now my ques is how jvm identify on which referenes you want to change (here id)because i have two references (one is original nd other is copy) – Jayesh Aug 20 '12 at 10:42
  • 1
    When the method is called the references are copied and in the method you use only the copied references. The objects are still only two. References are pointers to the objects. No objects are copied. Just the references(the pointers). This is important to understand - references and objects are different things. References are the variables which point to objects. (obj, obj1, obj2, temp) - they are all references, not objects. – Petar Minchev Aug 20 '12 at 10:45
0

As people have astutely pointed out, java is always pass by value.

It just so happens that the "value" of an object is it's memory address where it is stored on the heap. So here's what happens:

Object o = new Object();

The right hand side allocates space on the heap, we'll say at location 1000 The left hand side allocates a variable on the stack, we'll say at location 100, and due to the assignment contains the "value" of the object, which is 1000, it's location on the heap. Your memory now looks like this:

Stack
---------------------------
====== caller stack frame ==== 
100(o)    ==>     1000
==============================

Heap
------------------------------
1000   ==>   object data 1

Now you make a method call:

void foo(Object x) { .... }
foo(o);

A new stack frame is created (obviously on the stack) for the method call. A new variable is created on the stack, say at location 200, and given the "value" of the passed object, which is 1000, it's location on the heap.

So your memory looks like this before the method actually runs it's code

Stack
---------------------------
====== caller stack frame ====
100(o)    ==>     1000
==============================
====== foo stack frame =======
200(x)   ==>     1000
==============================

Heap
------------------------------
1000   ==>   object data 1

So if you now do this in your method:

void foo(Object x) {
   x = new Object();
}

You would be allocating a new object on the heap, let's say at location 2000, and assigning the method parameter variable to it's location so your memory now looks like this:

Stack
---------------------------
====== caller stack frame ====
100(o)    ==>     1000
==============================
====== foo stack frame =======
200(x)    ==>     2000    
==============================

Heap
------------------------------
1000   ==>   object data 1 
2000   ==>   object data 2

And when the method exits, the stack frame is dropped, and you're back to this:

Stack
---------------------------
====== caller stack frame ====
100(o)    ==>     1000
==============================

Heap
------------------------------
1000   ==>   object data 1
2000   ==>   object data 2

Notice that "o" still points to the same object data. The second allocated object (at location 2000) would now also be elligible for garbage collection.

Matt
  • 11,523
  • 2
  • 23
  • 33