-4

I expect a NullPointerException in the output of the following program, because inside the go method, c2 is nulled. But it works fine and print 200. Why?

class CardBoard {
    Short story = 200;
    CardBoard go(CardBoard cb) {
        cb = null;
        return cb;
    }
    public static void main(String[] args) {
        CardBoard c1 = new CardBoard();
        CardBoard c2 = new CardBoard();
        CardBoard c3 = c1.go(c2);
        System.out.print(c2.story); // dout here
    }
}
Andrew Thompson
  • 163,965
  • 36
  • 203
  • 405

7 Answers7

1

You're pointing the parameter of the go function to null, not the c2 variable. The go method might change the contents of the CardBoard parameter in its execution (e.g. the story parameter), but the object itself will not be 'nulled'.

Bohemian
  • 365,064
  • 84
  • 522
  • 658
drvdijk
  • 5,506
  • 2
  • 26
  • 47
1

Java uses pass by value semantics for method calls. This means that the value of the reference to c2 is passed to the go method, not the reference itself. Think of it this way. There are 4 memory slots, 3 containing the values that point to the objects created in main, these are named c1, c2, and c3, respectively, and another that will hold the value passed into the go method, named cb. When the function is called the value in c2 is copied to the slot cb. The go method then puts the value null in the slot cb. This, however, doesn't change the value in slot c2 - it remains the same as it was before the method call.

tvanfosson
  • 490,224
  • 93
  • 683
  • 780
1

Is Java pass-by-value?.

Lets say r2 is the reference to c2 , lets say 123 is the value of that reference. so r2 "holds" 123 which is nothing but c2's location.

Now when you call c1.go(c2), a new reference rN is created which holds 123, and is passed to the method. And when you do c2 = null, it is the refrence rN which becomes null and not c2.

Community
  • 1
  • 1
rocketboy
  • 8,990
  • 1
  • 31
  • 36
1

In Java parameters are passed by value, not by reference, so you are not modifying the variable c2, you are just "passing" the objet to which c2 is pointing to.

Maybe if you were using a language like C# you could do this in java:

class CardBoard {

    Short story = 200;

    CardBoard go(byRef CardBoard cb) { // NOT REALLY ALLOWED, Compilation error
        cb = null;
        return cb;
    }

    public static void main(String[] args) {
        CardBoard c1 = new CardBoard();
        CardBoard c2 = new CardBoard();
        CardBoard c3 = c1.go(byRef c2); // NOT REALLY ALLOWED, Compilation error
        System.out.print(c2.story); // dout here
    }
}

then you would be modifying c2 itself, but the only thing you could modify would be the internal state of the object that you pass (invoking something like myObj.setSomething(x)).

morgano
  • 16,553
  • 9
  • 42
  • 51
0
  • A reference to c2 is passed to the go method.
  • the reference is assigned to the parameter cb
  • the method code assigns a null to the parameter variable

All this has no effect on the contents of the c2 variable outside the go method

Bohemian
  • 365,064
  • 84
  • 522
  • 658
0

To get your expected result try to use the

`System.out.print(cb.story);`

inside the go method after nulling cb.

Or

System.out.print(c3.story); // dout here

Now in your case you are returning null which is assigned to c3. So your are not modifying the c2 variable.

The best explaination I have found about these doubts is here

All the answers and comments are worth reading.

Community
  • 1
  • 1
me_digvijay
  • 5,087
  • 5
  • 41
  • 78
0

I think you are misunderstood by how reference and objects works

Main Function

  CardBoard c1 = new CardBoard();

c1 |100| Address  ---points to---> Memory address at location 100

      CardBoard c2 = new CardBoard();
c2 |400| Address  ---points to---> Memory address at location 400

      CardBoard c3 = c1.go(c2);
c3 |600| Address  ---points to---> Memory address at location 600

      System.out.print(c2.story); // dout here

go Function

 CardBoard go(CardBoard cb) {

cb |400| Address  ---points to---> Memory address at location 400

New cb reference is created which also points to memory location where c2 is pointing(Note, cb and c2 are two different reference but pointing to same memory location)

     cb = null;
Above line changed cb reference to null, still c2 is pointing to same memory location.
      return cb;
  }

So when go function returned there is no change to c2.

Try changing story variable on cb reference, and you will see it affect to c2 variable as well.

cb is created in different method stack then where c1, c2 and c3 is created

Jayesh
  • 5,547
  • 10
  • 42
  • 75