javaobjectreferencepass-by-value

If Java is a "call-by-value" language then why is this happening?


See the test code:

class Node
{
    int num = 0;
}

class TestPassByReference
{
    void increaseByOne(Node N)
    {
        N.num++ ;
    }

    public static void main(String args[])
    {
        Node N = new Node() ;
        TestPassByReference T  = new TestPassByReference() ;
        T.increaseByOne(N) ;
        System.out.println("num = "+N.num) ;
        T.increaseByOne(N) ;
        System.out.println("num = "+N.num) ;
        T.increaseByOne(N) ;
        System.out.println("num = "+N.num) ;
    }
}

Which gives the result:

num = 1
num = 2
num = 3

The problem here, is that since Java is call by value then the num attribute of Node should have remained 0.

I think that this is due to creation of an object T, which would have contained an object N. But there is no attribute in T to save a Node like object. So how is this happening?

Any help is nefariously appreciated.

Moon.


Solution

  • Java is call-by-value in the sense that references are passed-by-value.

    This means you can change the internal state of the object you passed N (e.g. by modifying the num field's value) but you cannot reassign N to a new object (e.g. N = null; or N = new Node();).

    class Node
    {
        int num = 0;
    }
    
    class TestPassByReference
    {
        void increaseByOne(Node N)
        {
            N.num++ ;
            System.out.println("num value is:" + N.num);
        }
    
        void increaseByOneThenChange(Node N)
        {
            // increase by one as before
            N.num++;
            // change the reference to a new object
            N = new Node();
            System.out.println("num value is:" + N.num);
        }
    
        public static void main(String args[])
        {
            Node N = new Node() ;
            TestPassByReference T  = new TestPassByReference() ;
            T.increaseByOne(N) ;
            System.out.println("num = "+N.num) ;
            T.increaseByOne(N) ;
            System.out.println("num = "+N.num) ;
            T.increaseByOne(N) ;
            System.out.println("num = "+N.num) ;
    
           // now try this method to see the difference
           T.increaseByOneThenChange(N);
           // N here is the original object, whose `num` value was incremented
           // but the reference remains unchanged by the above method
           System.out.println("num = "+N.num) ;
        }
    }
    

    In the second case, only the reference that was passed to the method changes thus being visible only in the method's body (N will no longer refer the original object here), but the original one remains the same.