2

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?

  • Read this link http://www.thejavageek.com/2013/08/24/pass-by-value-or-pass-by-reference/ – Prasad Kharkar Sep 12 '13 at 11:51
  • 3
    Java is pass by value always, but in the case of objects, it's pass *reference* by value. – Michael Berry Sep 12 '13 at 11:52
  • 1
    `DumObj` is a reference, not an object – Peter Lawrey Sep 12 '13 at 11:53
  • I'm sure at least one of the 60 answers to the [Is Java "pass-by-reference"?](http://stackoverflow.com/questions/40480/is-java-pass-by-reference) question will explain it in sufficient detail. – Bernhard Barker Sep 12 '13 at 11:53
  • The problem with Java, I think, is it claims to noob programmers *"Hey come on here, Java has no pointers at all, there is no need to understand pointer arithmetic at all! Leave the headaches you have gain with C++ and come to Java!"*. But **the first thing you need to understand function calls in Java is that variables are just really pointers** – Manu343726 Sep 12 '13 at 12:04

5 Answers5

2

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.

Brian Agnew
  • 268,207
  • 37
  • 334
  • 440
  • There's a typo... "you can change the reference". Unless you mean that the reference can be changed inside the method, but it's not the same reference as outside of it... – Kayaman Sep 12 '13 at 11:53
  • So you can modify the object's variables but not the object itself, because doing so would point to a different object on the heap? –  Sep 12 '13 at 13:13
  • Thanks folks, much obliged. –  Sep 13 '13 at 09:21
2

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.

Tim S.
  • 55,448
  • 7
  • 96
  • 122
0

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.

dwarduk
  • 919
  • 1
  • 5
  • 8
0

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.

Manu343726
  • 13,969
  • 4
  • 40
  • 75
0

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.

TheGraduateGuy
  • 1,450
  • 1
  • 13
  • 35