Jump to content

call by refrence

- - - - -

This topic has been archived. This means that you cannot reply to this topic.
8 replies to this topic

#1
eman ahmed

eman ahmed

    Learning Programmer

  • Members
  • PipPipPip
  • 79 posts
is there call by reference in java?

Quote

public class test {
int a;

public test (int b){
a=b;
}
//it's work
public static void swap1(test x,test y){
int temp=x.a;
x.a=y.a;
y.a=temp;
}
//not work
public static void swap2(test x,test y){
test temp=x;
x=y;
y=temp;
}
public static void main(String[] args) {
test x=new test(2);
test y=new test(5);
swap2(x,y);
System.out.println(x.a+" "+y.a);

}

}
why method swap2 doesn't work ?
but swap1 working

Edited by eman ahmed, 21 September 2010 - 10:26 PM.


#2
dbug

dbug

    Programmer

  • Members
  • PipPipPipPip
  • 155 posts
Objects in Java are always referenced by variables (variables doesn't containt objects, they contain references to objects). When you do something like this:

Object obj = new Object();
What really happens is that a new object is created and a reference to it is assigned to variable obj.

When you pass an object as an argument of a function, you are really passing a copy of the reference. If you use this reference you can modify the object (like you do in swap1), but if you change the value of the argument variable, you are only modifying the local copy of the reference. This doesn't change anything in the variables of the calling function (like happens in swap2).

#3
Fae

Fae

    Learning Programmer

  • Members
  • PipPipPip
  • 80 posts
I'm honestly not sure; I tried this, and it seemed to swap them properly during Swap2, but after Swap2, the values for x.a and y.a seem to revert to their original state:


public static void swap2(test x,test y){

System.out.println("swap2");

test temp=x;

System.out.println("temp=x");

System.out.println("temp = "+temp.a+", x = "+x.a+", y = "+y.a);

x=y;

System.out.println("x=y");

System.out.println("temp = "+temp.a+", x = "+x.a+", y = "+y.a);

y=temp;

System.out.println("y=temp");

System.out.println("temp = "+temp.a+", x = "+x.a+", y = "+y.a);

}


here's my output:
swap2
temp=x
temp = 2, x = 2, y = 5
x=y
temp = 2, x = 5, y = 5
y=temp
temp = 2, x = 5, y = 2

2 5 //this is the end result from System.out.println(x.a+" "+y.a);

...so yeah, they do swap correctly inside the method. I'm not sure why, but I'd hazard a guess...
My first thought was that if you pass a instance of a class to a method as an argument (In this case, x and y are passed to Swap2 expecting two objects of type 'test'), then you reassign the object, you're reassigning it only to the local instances of x and y, and local variables and instances are lost when a method closes... basically, when you do the '=' operator on an instance of a class, you're making a 'copy' of the original class that contains the pointers to the memory location of the original data.

The reason the first one works is because you're explicitly editing the original integer (because swap1's test x refers to Main's test x, which points to the memory location of integer x.a), but in swap2, you're making a copy of test y into test x (when you do x = y; so test y will still refer to test y from Main, but test x in swap 2 now refers to test y in main as well, while 'temp' holds the references to test x and the pointers to the memory location where its integer is stored).

So, basically, when you run swap 2, you're copying test x and test y over to the arguments of swap2, then you swich what the local variables in swap 2 point to, which does not change the original data, nor does it change what the original test c and test y point to in Main.

...I think.

If someone else comes along and either corrects me, or explains this better, that would be cool ^^
I'll ask a lot of questions (most of them probably stupid stuff). Bear with me, i'm still learning! ^_^ Also, I'll try to answer as many questions as I can as well, but I'm not very good yet. I'm sure I'll be of more use once I get better :)

#4
Sinipull

Sinipull

    Programming Expert

  • Members
  • PipPipPipPipPipPip
  • 386 posts
So, basically, when you run swap 2, you're copying test x and test y  over to the arguments of swap2, then you swich what the local variables  in swap 2 point to, which does not change the original data, nor does it  change what the original test c and test y point to in Main.
That's it. The variables x and y in the method are separate from the fields x and y.

Posted Image

ofcourse variable x and variable y are lost after program exits the method, so no point in changing them in reality.

By the way, i think i've never had a need to swap my objects like that, but if you really need it for some reason, just do it in your current method, do not build special "swap" method for that.
Test x = new Test(5);
Test y = new Test(2);
Test temp = x;
x = y;
y = temp;
Posted Image

#5
Fae

Fae

    Learning Programmer

  • Members
  • PipPipPip
  • 80 posts
Awesome, thanks Sinipull ^^ Nice visual aids too :)
I'll ask a lot of questions (most of them probably stupid stuff). Bear with me, i'm still learning! ^_^ Also, I'll try to answer as many questions as I can as well, but I'm not very good yet. I'm sure I'll be of more use once I get better :)

#6
eman ahmed

eman ahmed

    Learning Programmer

  • Members
  • PipPipPip
  • 79 posts
thanks all for help
now I understood why swap2 doesn't work .
but if the prameter to method swap1 are copy of x and y ,so I change the copy .why x,y changes ?????

#7
Fae

Fae

    Learning Programmer

  • Members
  • PipPipPip
  • 80 posts
Java stores primitive data types like int, in a memory location, and any object, method, class etc... that created that object has the reference that points to where that data is stored in memory. In Swap1, you were using those references to change the data stored in x.a and y.a directly; in Swap2, you were swapping over the references to the data, and leaving the data itself unchanged, so when the Main method printed out the data stored in those memory locations, the versions of test x and test y from Main still pointed to the original locations of x.a and y.a, and because you did not change the data directly (you only swapped the references over in Swap2), you get the same output as the input you wrote into these variables at the start.
I'll ask a lot of questions (most of them probably stupid stuff). Bear with me, i'm still learning! ^_^ Also, I'll try to answer as many questions as I can as well, but I'm not very good yet. I'm sure I'll be of more use once I get better :)

#8
Roman Y

Roman Y

    Programmer

  • Members
  • PipPipPipPip
  • 189 posts
not really a good idea to make an instance variable public so it could be accessed by x.a why not make the test class like this:


public class test

{

   private int value;

   

   public test(int v)

   {

      value = v;

   }

   public int getValue()

   {

      return value;

   }

   public void setValue(int v)

   {

      value = v;

   }



   public static void swap(test v1, test v2)

   {

      int temp = v1.getValue();

      v1.setValue(v2.getValue());

      v2.setValue(temp);

   }

}

you don't really swap references but the result should be the same...

#9
Sinipull

Sinipull

    Programming Expert

  • Members
  • PipPipPipPipPipPip
  • 386 posts
Roman it's a Test class. It's not about getters and setters :)