0

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

I am trying to understand the difference between the 2 Java programs written below:

 public class Swapping {

public static void main(String[] args) {

    IntWrap i = new IntWrap(10);
    IntWrap j = new IntWrap(20);

    swap(i, j);
    System.out.println("i " + i.i + ", j " + j.i);
}

public static void swap(IntWrap i , IntWrap j){

    int x = i.i;
    i.i = j.i;
    j.i = x;

    System.out.println("i " + i.i + ", j " + j.i);
}

}

public class IntWrap {

int i;
public IntWrap(int i){
    this.i = i;
}

}

Output :

i 20, j 10
i 20, j 10

And second one:

public class Swapping {

public static void main(String[] args) {

    Integer i = new Integer(10);
    Integer j = new Integer(20);

    swap(i, j);
    System.out.println("i " + i + ", j " + j);
}

public static void swap(Integer i , Integer j){

    Integer temp = new Integer(i);
    i = j;
    j = temp;

    System.out.println("i " + i + ", j " + j);
}

}

Output :

i 20, j 10
i 10, j 20

I am not able to understand that I even though I am passing the Integer object, it should get swapped in the original program. What difference did it created if I wrote the wrapper class on the top of it as I am again passing the object only.

halfer
  • 19,824
  • 17
  • 99
  • 186
ASingh
  • 475
  • 1
  • 13
  • 24

4 Answers4

4

All method parameters, including object references, are passed by value in Java. You can assign any value to the method parameter - the original value in the calling code will not be modified. However you can modify the passed object itself and the changes will persist when the method returns.

There are old Holder classes in J2SE API, specially designed to support calls to methods with "returnable parameters" (IntHolder or StringHolder, for instance). They are mostly used with generated code from IDL language as IDL requires support for in, out and inout parameters. These holders are very uncommon in other code.

You can also simulate passing by reference by using arrays:

String [] a = new String[1];  String [] b = new String[1];

void swap(String [] a, String [] b) {
   String t = a[0]; a[0] = b[0]; b[0] = t;
}
Audrius Meškauskas
  • 20,936
  • 12
  • 75
  • 93
1

Ups. Integer objects are immutable in Java. You can not change their internal values neither from other method, neither at all. Only create new Integer object.

Andremoniy
  • 34,031
  • 20
  • 135
  • 241
  • That is not exactly the issue - in one case he modifies a field of an object whereas in the other case he reassigns an object. It would have the same effect with a mutable object. – assylias Jan 14 '13 at 09:01
  • 1
    @assylias May be we have misunderstanding about my answer. In 1st case he just changing fields values of `IntWrap` object. Its ok. In 2nd one he tries to change references of `Integer` object. He couldn't work with `Integer` objects in other way because of their immutable nature (there aren't any `setValue` for them and bla-bla). But explicit description of WHY he could not change reference from other method is really needed, I agree. – Andremoniy Jan 14 '13 at 09:17
1

Java uses call-by-value to pass all arguments.When you pass the object to a function, the object reference(address of object) gets passed by value.In the second program swap, you are assigning i=j and j=temp. So i=address of 20 j=address of 10(new object) But after return from swap, in the main program i is still pointing to 10 and j is pointing to 20.Thats why you are getting 10 and 20 back in main program.

But in first program, you are passing the address of your objects to swap function and in the swap function you are modifying the content of object pointed by these addresses.That is why, it is getting reflected in main method.

Renjith
  • 3,274
  • 19
  • 39
0

(If you don't know about pointers and references I suggest you go over them a bit, then the world will make more sense - Intro to Pointers)

Putting it down to the most simplest explanation, there are 2 ways java passed everything back and forth:

  • Pass-by=Value: Used for immutable objects (String, Integer, Double, etc.). These values cannot change with one exception, if you recreate the object.

       String x = "World"; <- String x = new String("World");
       x = "Hello"; <- x = new String("Hello");
       x = x + " World"; <- x = new String("Hello" + " World");
       printOutString(x); <- printOutString("Hello World");
    

Held at one memory location. Any alteration creates a new object with no relation to the previous and look at a separate memory location.

  • Pass-by-reference: Used for non-immutable objects (Classes, int, double, etc.). These values can be changed and still keep their old place in memory.

      int i = 1;
      i = 2; <- value at <reference-to-memory-as-value> = 2;
      i = i + 1; <- value at <reference-to-memory-as-value> + 1;
      printOutInteger(i); <- printOutInteger(value at <reference-to-memory-as-value>);
    

Any change to this object is done to the memory location. Therefore the location never changes (unless you create a new object).

The same is happening in your programs. The objects that say one thing in the method, then revert to the previous values. You are, in a way, Operator Overloading. You assign new values to the objections (Integer in this case) that you are sending, BUT you have passed the values which means Integer i within the method, because Integer is immutable, is looking at a different memory location to the Integer i in the main method. Therefore, when the method exits, the objects you passed are disposed of and Integer i and j now look at their original memory locations.

When you passed the classes with the int objects, as they are NOT immutable the memory locations were passed (by value) and the values at those locations were worked with. That is why the changes here were shown in the original objects.

I hope this helps

Skepi
  • 478
  • 3
  • 12