Question

Ok bit of an odd question. I have the following code, which just creates a simple java object called DumObj and sets a string value using a setter method. Then a few methods are called from a TestBed class using the DumObj as a parameter.

I initially thought that calling TestBed.updateId(DumObj) would not affect my DumObj, and the initial value of ID that was set to "apple" would stay the same. (Because of the whole pass-by-value thing)

However the value of ID was set to the updated value of "orange". Ok I thought, that's weird, so I wrote another method, TestBed.setToNull(DumObj). This method just sets DumObj to null, so when I call the getId() method I was expecting to get a null pointer exception.

However the output I got was the value of ID still set to "orange".

Code is as follows :

    public static void main(String[] args) 
    {   
            TestBed test = new TestBed();
            DumObj one = new DumObj();

            one.setId("apple");
            System.out.println("Id : " + one.getId());

            test.updateId(one);
            System.out.println("Id : " + one.getId());

            test.setToNull(one);
            System.out.println("Id : " + one.getId());
    }

    public void updateId(DumObj two)
    {
            two.setId("orange");
    }

    public void setToNull(DumObj two)
    {
            two = null;
    }

Output is as follows :

    Id : apple
    Id : orange
    Id : orange

It's probably something really simple I'm overlooking, but can someone explain this behaviour to me? Is Java not pass-by-value?

Was it helpful?

Solution

When you write

DumObj one = new DumObj();

it's important to realise that one is not a DumObj - it's a reference to DumObj, and references are passed by value.

So you're always passing by value, and you can change the passed reference (so your passed reference now points to a different object). However, your object itself could be mutable, so this:

   one.setValue(123);

will change the referenced object. When you call this:

public void setToNull(DumObj two)
{
        two = null;
}

you're changing the passed reference (remember - it's been passed by value and is local to the method!) and so your original object and original reference are not affected.

OTHER TIPS

When you do:

two = null;

You are only setting the two variable reference to null. The object that it was pointing to still exists, and is referenced by one.

On the other hand, when you do:

two.setId("orange");

You are modifying the object that is referenced by both one and two.

Java is kind-of "pass reference by value" for objects. So in setToNull(DumObj two), two is a reference to an object. If you say two = null;, that now makes two a reference to not an object; it doesn't change the object. If, on the other hand, you do something like two.setId("blue"), you are changing the object that two references.

When you call updateId the new reference variable two and old reference variable one both referring to same object in heap so changing one gets reflected in other reference variable.

now when you call setToNull again new reference variable two and old reference variable one both referring to same object.But here when you do two = null only reference variable two point to null object. but reference variable one still pointing to same object.When you do two==null ,you are not changing any value in object referred by it but instead you are referring reference variable to null.

In case in setToNull method you write two=new DumObj(); then a new object in heap will be created and two will point to this new object .and then for ex if you write two.setId("banana");

and in your main code if you write one.getId() inside syso then it will print orange not banana.

hope i helped.

Yes, Java is pass by value. But your variables are really pointers to the object allocated on the heap. So what its passed by value is the pointer, not the object.

In your examples:

public void updateId(DumObj two)
{
        two.setId("orange");
}

The first passes the variable (pointer) by value, that is, updateId() recieves a copy of the pointer. But what you are doing here is to modify the object pointed by the pointer. So the object was modified when you return to the caller function.

public void setToNull(DumObj two)
{
        two = null;
}

In the second case, you are assigning null to a copy of the original pointer, not the original pointer itself, so that function call has no effect at all in the origial variable.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top