wood burning stoves 2.0*
The moose likes Java in General and the fly likes field intialization Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Android Security Essentials Live Lessons this week in the Android forum!
JavaRanch » Java Forums » Java » Java in General
Bookmark "field intialization" Watch "field intialization" New topic
Author

field intialization

Derik Davenport
Ranch Hand

Joined: May 30, 2011
Posts: 53
I have a problem with field intialization. It doesn't seem to occur until after my constructor starts and this causes me problems. details follow.

Somewhere in my code I attempt to create an instance of the MyWidget class below.


This calls the appropriate constructor of MyWdiget, which contains nothing but a call to one of the constructors of the super class, AbstractWidget, with the same arguments. In turn, the super's constructor calls the build() method which is defined in the subclass (MyWidget in this case). In one concrete subclass of AbstractWidget, MyWidget, there is a field that holds an object, , that helps with the build functionality. Not all subclasses of AbstractWidget would need this field which is why it is not defined there. Anyway, when MyWidget.build() is called from the super's constructor I find that the builder is not defined! More precisely, it is still null because, it seems, the initialization of builder has not taken place before the call to super(info);

What is up with that? I thought fields would be intialized _before_ constructor code, even before the call to super(info). If not it creates a problem because the call to super() must be the first line of MyWidget's constructor and AbstractWidget's constructor doesn't know about this field so it can't initialize it. Further, I don't want to initialize it inside the build() method of MyWidget because build is called from other routines (outside the constructor).






Paul Clapham
Bartender

Joined: Oct 14, 2005
Posts: 18541
    
    8

Derik Davenport wrote:More precisely, it is still null because, it seems, the initialization of builder has not taken place before the call to super(info);

What is up with that? I thought fields would be intialized _before_ constructor code, even before the call to super(info). If not it creates a problem because the call to super() must be the first line of MyWidget's constructor and AbstractWidget's constructor doesn't know about this field so it can't initialize it. Further, I don't want to initialize it inside the build() method of MyWidget because build is called from other routines (outside the constructor).


Unfortunately you have fallen into one of the more subtle and annoying traps in Java. You have diagnosed what is happening correctly, but you are still in denial. Fields in a subclass are not initialized until the superclass is completely constructed, is what it amounts to; people who read the JVM could explain it more clearly, but it's what you are seeing, right? So that means that calling a overridable method from a constructor is a dangerous practice because you could run into this initialization-order issue.

In other words, you're going to have to restructure your design so that the build() method isn't called from a constructor of AbstractWidget. I don't know how you might do that; perhaps you could move the initialization of the variable into the build() method instead of leaving it where it is? You do have to do something, though, because you're stuck with the order of initialization decreed by Java.
Derik Davenport
Ranch Hand

Joined: May 30, 2011
Posts: 53
A little research, and Paul's helpful post, has shown that the initialization of the builder field takes place after the call to the constructor of the super class and before any additional code in the constructor. Upon reflection, I guess it has to be that way. With this in mind, I changed the way builder is initialized. This method will only initialize the builder if the parent's constructor doesn't do it. In the code below build calls the same function to initialize builder, but it wouldn't need to work that way.

EDIT: 4:45pm to correct code

 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: field intialization
 
Similar Threads
Can constructors throw Exceptions?
why abstract class can have constructors
how do i track a child's onload event
Treat an object as a constant within a method
A question about casting from Object[]