Thursday, September 16, 2004

Does Java pass Objects by reference?

You often hear that Java passes primitives by value and Objects by reference. Unfortunately, this is misleading. A reference has a specific meaning in programming terminology. A reference is the variable itself. Its not a pointer, its not a copy, its the actual variable. This means that if a variable is passed by reference to a function and the function assigns another value to it, the changes are visible outside the function. C++ implements references faithful to the original meaning while Java does not.
#include <iostream.h>

class Ref
{
        public:
        int one(int& it) { it = 1; } // Reassign variable
        void two(int& it) { it++; }  // Change variable
};

int main()
{
        Ref ref;

        int item = 0;
        ref.one(item);
        cout << "Item is " << item << endl;
        ref.two(item);
        cout << "Item is " << item << endl;

        int* i = new int(0);
        ref.one(*i);
        cout << "I is " << *i << endl;
}
Prints:
Item is 1
Item is 2
I is 1
Java on the other hand, passes a copy of the reference. This means that any changes to the variable are preserved, but you cannot reassign the variable to point to something else within the traditional meaning of "reference."
import java.util.Date;

public class Ref
{
        public void one(Date item) { item = new Date(); }

        public void two(Date item) { item.setTime(365*24*60*60*1000L); }

        public static void main(String[] args)
        {
                Date item = new Date();
                item.setTime(0);
                Ref ref = new Ref();
                ref.one(item); // Change not reflected here
                System.out.println("Item is "+item);
                ref.two(item); // Change is reflected here
                System.out.println("Item is "+item);
        }
}
Prints:
Item is Wed Dec 31 19:00:00 EST 1969
Item is Thu Dec 31 19:00:00 EST 1970
The net effect of this is that a Java function can change the Object passed to it, but any reassignment to something else is lost. Many argue that this is indeed safer and C++ funtionality can be achieved by having the function return the new value and let the caller assign it to the actual variable. It also protects the programmer from having to overload the = operator when calling outside code to ensure that the reference is not reassigned. Click here for good reference on References