Ryan Marv
Ryan Marv

Reputation: 109

Initialization order of nested classes

I have this piece of code, and the compiler's returns with NullPointerException where I try to create BtnAct. I've read much about initialization but still haven't come across in what order inner classes are initialized. Can someone help please?

public class BaseClass{
    static Myclass myClass;
    public static void main(){
        myClass = new MyClass;
    }
}
class MyClass{
    NewClass newClass;
    public MyClass(){
        newClass = new NewClass();
    }
    class BtnActn extends AbstractAction {
        BtnActn() {
           super("Button");
        }
        @Override
        public void actionPerformed(ActionEvent e) {
            //blabla
        }
    }
}

class NewClass{
    JButton button;
    public NewClass(){
        button = new JButton(BaseClass.myClass.new BtnActn()); //NullPointer.ex here
    }                                                          
}

Upvotes: 1

Views: 1173

Answers (2)

Stephen C
Stephen C

Reputation: 718886

I've read much about initialization but still haven't come across in what order inner classes are initialized.

Class initialization is about the initialization of a classes static fields and execution of static initializer blocks. However, an inner class in Java is not allowed to have any static fields or static initializers. (See JLS 8.1.3.) Hence (real) class initialization for inner classes is moot. It makes no difference when it happens ... 'cos there is nothing in an inner class to initialize.

The real problem here is that while you have a static field, its actual initialization (to a non-null value) is not done during static initialization. Rather, it would happen when some part of your code explicitly calls BaseClass.main(). However, none of your code does that ... and hence myClass is going to be null when you try to use it.

Again ... I stress ... this is not an issue of how static initialization works, because your code doesn't use static initialization to initialize the field in question.

Upvotes: 1

Maxime Jeanmart
Maxime Jeanmart

Reputation: 56

Here is what happens:

  1. Base class tries to create an instance of MyClass. Please notice that at that time it's not assigned to myClass yet
  2. the new instance of MyClass tries to create an instance of NewClass. Please notice that at that time, it's not assigned to the variable newClass yet
  3. the new instance of NewClass tries to create a new instance of JButton. For that purpose, it first needs to access BaseClass.myClass. Unfortunately, the object BaseClass.myClass is already in memory (it's in the process of being initialized at that time), but it's not assigned to the BaseClass.myClass variable yet. So it makes a NullPointerException.

So you need to separate the initialization of your Button from the initialization of myClass variable in BaseClass.

Upvotes: 2

Related Questions