aspose file tools*
The moose likes Beginning Java and the fly likes Null Pointer exception when accessing a static instantiated object with in the instance of a class. Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » Beginning Java
Bookmark "Null Pointer exception when accessing a static instantiated object with in the instance of a class." Watch "Null Pointer exception when accessing a static instantiated object with in the instance of a class." New topic
Author

Null Pointer exception when accessing a static instantiated object with in the instance of a class.

Kalyana Chakravathy
Greenhorn

Joined: Nov 04, 2009
Posts: 8
Hi,
I am new to java and have written a small piece of code.

Test.java :





On running Run it gives me a NPE,

[jkalyana@toddler ~]$ javac Test.java
[jkalyana@toddler ~]$ vim Run.java
[jkalyana@toddler ~]$ javac Run.java
[jkalyana@toddler ~]$ java Run
Exception in thread "main" java.lang.ExceptionInInitializerError
at Run.main(Run.java:3)
Caused by: java.lang.NullPointerException
at Test.enter(Test.java:10)
at Test.<init>(Test.java:7)
at Test.<clinit>(Test.java:4)
... 1 more


I had a doubt and changed the Test.java to this,



On moving the declaration of Test below map, it runs,

[jkalyana@toddler ~]$ java Run
Key = dummy1, Value = dummy2

Can anyone tell me why this is so.
Lee Kian Giap
Ranch Hand

Joined: Jan 23, 2008
Posts: 213
Okay, before I explain the flow of the code you have written ... you have to understand the statment below first:

"The order of initialization is statics first, if they haven't already been initialized by a previous object creation, or first invoke of any static method/field of the class. After the initialization for statics complete, only then the turn for non-static object"

Now , follow my explanation

When you run "java Run", the "public static void main" method of class Run invoke. However before this method invoked, class Run loaded and initialized. After this, the "public static void main" method call Test.display() which is a static method of class Test.

Now, do you notice that the display() is the first invoke of static method of the class Test ? So, before these method progress, class Test loaded and initialized. Here start the initialization of class Test, the 1st line is "private static Test instance = new Test();", so it run the constructor "Test()" to create a Test object, and within the constructor it call "enter()", then it execute "map.put("dummy1","dummy2");". However, at this point the map haven't been initialized which is still null, so the NPE thrown. Understand ?

On moving the declaration of Test below map, it runs


If you understand my explanation above, I think you can figure out this yourself. Since the map is the 1st line, it is initialize before Test, which means before the method enter() invoked which access map.



Now, I bring out a good practice which one need to follow is , "In a constructor, you can call superclass method, because superclass surely is completely loaded and initialized. However, in a constructor, one should not (although you can) call method from its own class because it will give a non guarantee behavior where its own class haven't completely initialized"

All The Best, hope my explanation help you to progress.


SCJP 6, SCWCD 5, SCBCD 5
Embla Tingeling
Ranch Hand

Joined: Oct 22, 2009
Posts: 237
It's because in the first case the map variable is null when you do,

private static Test instance = new Test();

This means this will fail in the enter method,

map.put("dummy1","dummy2"); // error - map is null

When you change the order map isn't null anymore so it works.
Kalyana Chakravathy
Greenhorn

Joined: Nov 04, 2009
Posts: 8
Lee Kian Giap wrote:
Now, I bring out a good practice which one need to follow is , "In a constructor, you can call superclass method, because superclass surely is completely loaded and initialized. However, in a constructor, one should not (although you can) call method from its own class because it will give a non guarantee behavior where its own class haven't completely initialized"

All The Best, hope my explanation help you to progress.



Thanks, Now I understood how static declarations are instantiated in the first place. To just check if I understood correctly or not, I made the Test declaration in it non static and removed the getInstance() method and ran it. Now whatever may be the order it prints the values as static objects are instantiated first. Only in the previous case since both were static it followed the order of declaration. I made it like this,



One question, you said it better to always call the superclass from the constructor. By default the default superclass constructor is called. Also the object I want to refer or load when the object is instantiated is within that class and not the super class. So I guess it makes sense to call it from the constructor, or have that piece of code within the constructor itself. How does having superclass solve it. Do you say, I must put the static variable in the superclass ?
Lee Kian Giap
Ranch Hand

Joined: Jan 23, 2008
Posts: 213
Thanks, Now I understood how static declarations are instantiated in the first place. To just check if I understood correctly or not, I made the Test declaration in it non static and removed the getInstance() method and ran it. Now whatever may be the order it prints the values as static objects are instantiated first. Only in the previous case since both were static it followed the order of declaration


Yes, !!! You get my point !!! This is a very important concept to build strong foundation, cheer !


One question, you said it better to always call the superclass from the constructor.


Sorry, I have to correct your sentence first. I didn't mean it is better to always call the superclass method from constructor. What I try to said is , you can call a superclass method in constructor will not give you such non-guarantee result which you encounter (where you need to arrange your static initialization) because at the point that the subclass calling a superclass method, the object of superclass is completely created (this is handle by compiler implicitly, and that is the reason why you have the keyword super in the subclass)
However, one should always avoid calling the method in the constructor of its own class, which will give you a non-guarantee behavior, this is the important point I trying to bring out !

So, I'm not trying to ask you to call superclass method for your situation by moving things into superclass. I just want to bring out the point that calling superclass method in constructor is SAFE. Hope you understand


By default the default superclass constructor is called. Also the object I want to refer or load when the object is instantiated is within that class and not the super class. So I guess it makes sense to call it from the constructor, or have that piece of code within the constructor itself. How does having superclass solve it. Do you say, I must put the static variable in the superclass ?


For your situation, as explain above, I'm not trying to ask you to call superclass. When one start to call a method of its own class in the constructor, this is the time to rethink what really you are trying to do. As refer to your code, map will be initialize everytime when a new Test object created, this might not be the case you want.

What I can see from your code is you are trying to initialize the map when you need it with a new Test object, my question here is are you actually prefer to initialize the map when class loaded instead of when instantiate a Test object since what I see your map is a static field which share among object.

So, my suggestion is as below by using static initialization


Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 39869
    
  28
kalyana cj wrote:. . . By default the default superclass constructor is called. . .
No, by default a superclass no-arguments constructor is sought. It is invoked if it exists. If not, you must provide a super( . . . ); statement.
 
 
subject: Null Pointer exception when accessing a static instantiated object with in the instance of a class.