0

I have a question regarding this code:

Object obj = null;
someMethod(obj);
System.out.println(obj.getId());
..
..
void someMethod(Object obj) {
    obj = new Object();
    obj.setId("Id1");
}

The above code is throwing NullPointerException. Can anyone tell me why is the object still null even after instantiating it inside the method?

Eran
  • 387,369
  • 54
  • 702
  • 768
Ramson
  • 229
  • 4
  • 12
  • 10
    Java is pass by value. – m0skit0 Feb 03 '15 at 11:33
  • 1
    cause u haven't stored the object. obj = someMethod(obj); – Vivek Singh Feb 03 '15 at 11:33
  • 1
    @m0skit0 pass by value-ish. – Deltharis Feb 03 '15 at 11:34
  • 2
    @Deltharis As long as you keep in mind what the value of a reference-typed variable is, Java is 100% pass-by-value. – Marko Topolnik Feb 03 '15 at 11:36
  • 1
    @Deltharis - Don't say things like that. It is misleading. – Stephen C Feb 03 '15 at 11:38
  • 1
    @Deltharis No. Java is 100% pass by value, you just have to understand what really is passed (the pointer is passed, not the object). – m0skit0 Feb 03 '15 at 11:39
  • The part about "remembering that it's the values of references" makes it an -ish in my book. It's important to remember people might come from different languages and after seeing a straight `pass by value` sentence might get wrong ideas about objects getting copied on the heap or whatnot. – Deltharis Feb 03 '15 at 11:41
  • @Deltharis I also come from different language. Let's take C as an example. When I declare a pointer and pass it to a function, I'm not passing it by reference, I'm passing it by value (even if it's a pointer). This is exactly what Java does. On the other hand, if I create an int then pass a pointer to that (which you can't do in Java), then I'm passing by value. I hope this clears your doubt about nomenclature. – m0skit0 Feb 03 '15 at 11:51
  • @Deltharis Hi, If I had instanciated it in prior and sent to the someMethod() and set the Id and returned the object. In that case, What would have been sent to the method as argument. I mean copy of the instantiated object or the same referrence? Thanks. – Ramson Feb 03 '15 at 11:51
  • @Ramson same reference - read http://stackoverflow.com/questions/40480/is-java-pass-by-reference-or-pass-by-value for some great in-depth explanations – Deltharis Feb 03 '15 at 12:01

7 Answers7

8

The call someMethod(obj) can't change the value of the obj variable (since Java is a pass by value language), so obj is still null after the call, and System.out.println(obj.getId()); throws NullPointerException.

An alternative that would work :

Object obj = someMethod();
System.out.println(obj.getId());
..
..
Object someMethod() {
    obj = new Object();
    obj.setId("Id1");
    return obj;
}
Eran
  • 387,369
  • 54
  • 702
  • 768
2

Java is pass by value, and you pass the reference to an object, not the object itself. I think it is very important to know this since this will let you understand how Java works much much better, so let's go step by step on your code and see why it doesn't work the way you expect.

Object obj = null;
someMethod(obj);
void someMethod(Object obj) {

Here, obj reference is copied (not the object instance, only the reference to it) then passed to someMethod.

obj = new Object();

Here you're overwriting obj value but only in the scope of the method. Note that obj reference in the caller (outside someMethod) has not changed, because it is a copy. After the method finishes, obj reference in this scope is discarded because we go out of scope, and you go back to the caller scope. In this scope, obj is still null. Thus

System.out.println(obj.getId());

obviously throws NullPointerException.

If you want to get the new reference from the method, you can return it and assign it in the caller scope, for example:

Object someMethod() {
    obj = new Object();
    // Do stuff with obj
    return obj;
}
Object obj = someMethod();
m0skit0
  • 25,268
  • 11
  • 79
  • 127
1

In Java you copy arguments when passing them to a method. When we are talking about objects, you pass copy of reference. So assigning object inside of your method -you are applying them to the copy of reference.

You need to wrap obj reference and pass wrapper inside, than use setter method to set obj reference.

Second solution would be to return you object from your method.

Beri
  • 11,470
  • 4
  • 35
  • 57
1
void someMethod(Object obj1) { // incoming obj1 with reference to obj
    obj1 = new Object();   // now when you do new Object() obj1 contains new reference
    obj1.setId("Id1"); // the object referred by the obj1 reference is updated 
}

Basically java uses pass by value. When you call the someMethod(obj), you are just passing the reference to the obj as an argument and not the object itself.When inside the someMethod, the object variable is initialized and now the obj1 inside the somemethod now contains reference to some other object(not the one you sent from the calling class).

So when your program returns to the calling class, the obj there again refers to the original reference that was sent initially ie to a null object. Hence you get a nullpointerexception. Note that when a method is invoked, it gets allocated its own stack frame, hence the obj1 inside somemethod() and obj inside the calling class' stack are different when the call returns back.

Sumeet Sharma
  • 2,573
  • 1
  • 12
  • 24
  • I think you answer is somehow confusing: *"java uses pass by value [...] you are just passing the reference to the obj"*. So, am I passing by value or by reference then? – m0skit0 Feb 03 '15 at 12:02
  • let me put it in terms of pointers. The value here is the pointer reference, hence pass by value. – Sumeet Sharma Feb 03 '15 at 12:39
  • Thanks, I fully understand it, I still think your phrase is confusing for someone that doesn't understand it. – m0skit0 Feb 03 '15 at 12:54
1

You get a NullPointerException due to the fact that the value of the variable obj has not changed. When you call the method someMethod and pass obj to it, then you passed obj by value and not by reference.

Yui
  • 74
  • 1
  • 11
0

Java passes method arguments by value: it makes a copy of the object that you gave as an argument as opposed to giving a reference to it to the method; any changes are made to the copied object (that you can then return and use), not to the actual object.

Bogdan Păun
  • 147
  • 8
0

Java passes by value the reference to an object.

At this point

someMethod(obj);

no object was created so the reference value is null.

If you update the reference variable inside the method somemethod() and return it to the obj variable you will see that then both references point to the same object.

fidudidu
  • 399
  • 3
  • 10