Java 嵌套类的初始化顺序

Java 嵌套类的初始化顺序,java,initialization,nested-class,Java,Initialization,Nested Class,我有这段代码,编译器返回NullPointerException,我试图在其中创建BtnAct。我已经读了很多关于初始化的书,但仍然没有看到内部类是以什么顺序初始化的。有人能帮忙吗 public class BaseClass{ static Myclass myClass; public static void main(){ myClass = new MyClass; } } class MyClass{ NewClass newClass;

我有这段代码,编译器返回NullPointerException,我试图在其中创建BtnAct。我已经读了很多关于初始化的书,但仍然没有看到内部类是以什么顺序初始化的。有人能帮忙吗

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
    }                                                          
}
发生的情况如下:

  • 基类尝试创建MyClass的实例。请注意,当时它还没有分配给myClass
  • MyClass的新实例尝试创建NewClass的实例。请注意,当时它还没有分配给变量newClass
  • NewClass的新实例尝试创建JButton的新实例。为此,它首先需要访问BaseClass.myClass。不幸的是,对象BaseClass.myClass已经在内存中(当时正在初始化),但它尚未分配给BaseClass.myClass变量。所以它产生了一个NullPointerException
  • 因此,您需要将按钮的初始化与基类中myClass变量的初始化分开

    我已经读了很多关于初始化的书,但仍然没有看到内部类是以什么顺序初始化的

    类初始化是关于类静态字段的初始化和静态初始化程序块的执行。但是,Java中的内部类不允许有任何静态字段或静态初始值设定项。因此,内部类的(实)类初始化是没有意义的。当它发生的时候没有什么区别因为内部类中没有要初始化的内容

    这里真正的问题是,虽然您有一个
    静态
    字段,但它的实际初始化(非空值)在静态初始化期间没有完成。相反,当代码的某些部分显式调用
    BaseClass.main()
    时,就会发生这种情况。但是,您的任何代码都不会这样做。。。因此,当您尝试使用它时,
    myClass
    将成为
    null


    再次。。。我强调。。。这不是静态初始化如何工作的问题,因为您的代码不使用静态初始化来初始化相关字段

    当调用嵌套实例类构造函数时,
    BaseClass
    的静态字段
    myClass
    应该是
    null
    。什么是
    BaseClass
    ,我假设myClass应该是
    static
    。当您尝试使用调试器调试程序时,会看到什么?myClass是静态的。也许Mena所说的是这样的,有没有一种方法可以告诉初始化方法停止在某个级别,让值赋值在基类中首先发生?我不知道这是怎么回事。BaseClass.myClass在构造函数完成之前不会被赋值,构造函数将被NPE,因为BaseClass.myClass没有被赋值。我以为实例的赋值是在从实例进行额外调用之前发生的,但我现在明白这有多愚蠢了。因此,实际上不可能只通过MyClass的初始化来完成我正在尝试做的事情。尽管找到解决办法并不难。谢谢你的回答。