Java · Pointers · Programming · reference

Java pass by reference vs pass by value

Whether Java passes parameters by reference or by value has been a source of confusion for a long time. There have been many great articles that have covered this topic, yet still it never fails to confound even seasoned programmers.

The real source of confusion has been use of word reference as used in Java programming language.  It would be a worthwhile exercise to understand the difference between a reference and a pointer as used in C/C++ as these are the grand daddies of all modern programming languages. Once we have understand this concept, understanding why Java behaves the way it does will be an easier task.

C/C++ Pointers and References

Pointer

int a;
int *ptr = &a;

Reference

int a;
int &ref = a;

Both pointer and reference contain the memory address of the variable a. But these still are different type of variables and are used differently.

Value assignment in pointers:

*ptr = 3; // uses the "*" in front of the variable to provide dereferencing

Value assignment in reference:

ref = 3;// references are used directly like the normal variables

In both the cases, value 3 is assigned to the variables they are pointing to.

Pointers allow arithmetic operation:

ptr++;

References DO NOT allow arithmetic operation:

ref++;// illegal code

Pointers can be used to point to different objects but references remain fixed once they are created.

Now, coming back to Java.
As per the specs, Java uses pass by reference for all objects. However, what is called as Reference by Java specs, in reality is a pointer in C/C++.  This causes a lot of confusions to everyone.

So, thumb rules for parameters in Java:

  1. Parameters in Java are ALWAYS pass by value.
  2. For primitives (int, float, boolean,char etc) the original value is passed by value to the method.  This means that the original variables in the caller method cannot be changed from inside callee method.
  3. For immutable objects like String, the parameter is passed by value.  So any changes made in the callee method has no effect on the variable in the caller method.
  4. For mutable objects, Java passes by reference (in reality a copy of the pointer to object is passed).  So any changes made to the object in the callee method will affect the same object in the caller method.  Since the copy of a pointer is passed, it is a local variable for that method.  Once the method is done, that copy of pointer is also lost.

Because of point 4, the normal way of swapping variables in another method does NOT work in Java.  When we swap the references inside a method, we are simply exchanging the pointer values without interchanging the actual objects in the Java heap.

The best way to understand this concept is by writing a small Java program.So here it is!

public class JavaPassByReferenceDemo {

    public static void main(String[] args) {

        //StringBuffer is a mutable type object
        StringBuffer sb = new StringBuffer("original");
        testMutableObjectParameter(sb);
        System.out.println(sb);

        //int is a primitive type
        int i = 0;
        testPrimitive(i);
        System.out.println(i);

        //String is an immutable type
        String s = "Original string";
        testImmutableObjectParameter(s);
        System.out.println(s);

        //swapping demo
        StringBuffer sb2 = new StringBuffer("sb2");
        StringBuffer sb3 = new StringBuffer("sb3");

        swapVariables(sb2,sb3);
        System.out.println("sb2 = "+sb2);
        System.out.println("sb3 = "+sb3);
    }

    public static void testMutableObjectParameter(StringBuffer sb) {
        sb = sb.append(" changed");
        System.out.println(sb);
    }

    public static void testPrimitive(int j) {
        j = 1;
        System.out.println(j);
    }

    public static void testImmutableObjectParameter(String s) {
        String g = s;
        g += " changed";
        System.out.println(g);
    }

    public static void swapVariables(StringBuffer sb2,StringBuffer sb3) {
        StringBuffer temp = sb2;
        sb2 = sb3;
        sb3 = temp;

        System.out.println("sb2 = "+sb2);
        System.out.println("sb3 = "+sb3);
    }

}
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s