// JP opened flex table

Click to See Complete Forum and Search --> : NullPointerException?


Norm
February 4th, 2002, 09:34 PM
Could anyone explain why this code gets a NullPointerException?
// BooleanNP.java

import java.awt.*;

public class BooleanNP {
boolean testing = true; // Control debug output
public BooleanNP() {
new MyWindow(new Frame());
}

class MyWindow extends Window {
// Constructor
public MyWindow(Frame f) {
super(f);
}
// Override to show when called and with what
public void setBounds(int x, int y, int w, int h) {
if (testing) {
System.out.println(" setBounds(i) to: "
+ x +","+ y + " " + w +"x"+ h);
}
super.setBounds(x, y, w, h); // pass on
}
} // end setBounds()

public static void main(String[] args) {
new BooleanNP();
}
} // end class
/* Output when executed:
Running: java BooleanNP

java.lang.NullPointerException
at BooleanNP$MyWindow.setBounds(BooleanNP.java:18)
at java.awt.Component.move(Unknown Source)
at java.awt.Component.setLocation(Unknown Source)
at java.awt.Window.<init>(Unknown Source)
at java.awt.Window.<init>(Unknown Source)
at BooleanNP$MyWindow.<init>(BooleanNP.java:14)
at BooleanNP.<init>(BooleanNP.java:8)
at BooleanNP.main(BooleanNP.java:27)
*/



It was originally imbedded in a much larger program and it took me a while to realize that the reference to the enclosing class holding the variable testing must not be initialized when setBounds() was called.
My fix was to make testing a local variable in the inner class and set it in the constructor after the call to super. That means I miss getting the println() on the first call. Oh well.

In general, how do you code overridden methods that might be called by the super Constructor to prevent this?

Norm

dlorde
February 5th, 2002, 12:40 PM
That's a doozy Norm! I also thought that the enclosing class reference wasn't fully initialized when setBounds(...) was called (because it was called from the constructor), but this isn't the case. If you step through a simplified example, you'll see that the first thing to happen is that the member variables get initialized. Extending this further, if you pull the window creation out of the constructor and put it into a separate method (makeWindow()?), and call that from main(...), so you're constructing the class object completely before calling the method, the problem still appears.

Some experimentation shows that if your member class tries to access a member of its enclosing class from an overridden method called by its superclass's constructor, the enclosing class will appear to be null. If it calls that method from its own constructor, everything is fine!

I'd call it a bug, but it's probably explained somewhere in the Java spec... ;-)

Dave

//JP added flex table