How Java passes variables

In my opinion one of the most confusing topics that Java has to offer is how it passes its variables. Two people can argue for over a page trying to say the same thing but not realize it until after.

The subject gets brought up mostly by C++ programmers transferring over to java. This is because in C++ you can choose how you want your variables to be passed ( by passed I mean used as an argument in a method/constructor) and you begin to realize how much it matters. Likewise it is good ( I’d argue necessary) to know how it is done in Java.

In C++ there are two main ways to pass a variable, pass by reference and pass by value.

  • pass by Value – Passing by value means you that when you give an object to a method, the method is never going to touch the object you passed it. Instead the method will copy the object an manipulate that.

    Passing by value is characterized by the fact that whatever you do inside of the method will have no effect on the variables on the outside. For example

    void f( int x, int y) {
         int temp = y;
         y = x;
         x = temp;
    }
    
    int main() {
        int x = 2;
        int y =3;
        f(x,y);
        cout < < x; // will print out 2
        cout << y; // will print out 3
    }
    

    So even though the program swapped the two variables in the method, it had no effect on the outside.

  • pass by reference – Passing by reference is the near opposite of passing by value. Instead of copying a new variable, the old ones are used. Now any changes made to the variables inside will have the same effect on the ones outside.

    Here is an example of passing by reference

    void f( int& x, int& y) {
         int temp = y;
         y = x;
         x = temp;
    }
    
    int main() {
        int x = 2;
        int y =3;
        f(x,y);
        cout < < x; // will print out 3
        cout << y; // will print out 2
    }
    

    This example will switch the numbers because it is altering the variables like they were the original ones.

That seems easy enough right? Well, unfortunately Java doesn’t do either. Yet depending on how you do it, the switch test could go either way.

What Java does is called passing the reference by value. I’m sure that doesn’t help much, possibly only makes it more confusing, so let me explain.

When you create an object Java assigns it a spot on the memory. Every time you use that object Java uses the variable to locate the Object in the memory.

Double pi = new Double(3.14);

In this example the variable pi is pointing to the a Double object in memory.

The key here is to realize that there is a difference between the variable and the object. Just because we said that pi = new Double(); does not mean that pi is exactly the same as the double, it simply points to the Double in memory.

pi = new Double(3.1415);

Now we create a new Double object in memory and tell pi to point to it. It does not take the previous Double’s place in memory. The previous Double will most likely just sit there until the Garbage Collector picks it up.

function(pi);
...
static void function(Double passedPi) {
    passedPi = new Double(3.14);
}

Now we are going to pass the variable to the function. Notice: we are not passing the object itself, just the variable that is pointing at it. This variable that is pointing at it is passed by reference.

So once we pass the variable we have pi that is pointing to the Double(3.1415) and when we enter the method passedPi is pointing towards Double(3.1415).

They are both pointing to the same object, but they are completely separated from each-other now. To prove this we will assign passedPi to a Double(3.14).

If you print out the values you will see that pi is still pointing at Double(3.1415) but passedPi is pointing at Double(3.14). There were no outside effects from the change.

So if you can’t assign new values to variables what can you do? The secret is to modify the memory itself not the pointer to the memory ie. You may modify the attributes of an object and it will apply all around.

Point myPoint = new Point();
myPoint.x = 2;
myPoint.y = 3;
swap(myPoint);

...

void swap(Point p) {
    int temp = p.x;
    p.x = p.y;
    p.y = temp;
}

That code will actually swap the x and the y values. This is because you are modifying the object that is in memory.

They key to remembering this is to separate the variables from the actual objects themselves, where the variable is simply a pointer to the Object.

For those that know C++/C it is effectively a pointer that you can’t selectively dereference.


3 Responses to “How Java passes variables”

  • Paul-Benoit Larochelle Says:

    Good show
    There are simpler way to explain that as Peter van der Linden did in his book “Just Java” but there is no error in the argumentation.
    Basically you can do:

    public void (MyObj x) {
    x.abc = z;
    }

    but you cannot do

    public void(MyObj x, MyObj y) {
    MyObj temp = x;
    x = y;
    y = x;
    }

    that would require ** in C++

    Good show

  • Ivana Fukalot Says:

    “The subject gets brought up mostly by C++ programmers transferring over to java.”

    Don’t see why that would be the case. Java’s references are identical to pointers and are passed in the same exact way too – by value.

    The only people that I see asking this question are beginners who still don’t know what a pointer is and how it works.

  • syfran Says:

    Most java beginners don’t even know what it means to ‘pass by reference’. C++ programmers are going to be taught what the difference between them are from the start and have to learn to work with each one. A java beginner can safely ignore it in the beginning.

    Just my opinion though :/

Leave a Reply