嵌套类的初始化顺序

时间:2014-09-01 12:14:33

标签: java initialization nested-class

我有这段代码,编译器返回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
    }                                                          
}

2 个答案:

答案 0 :(得分:2)

以下是发生的事情:

  1. 基类尝试创建MyClass的实例。请注意,那时它尚未分配给myClass
  2. MyClass的新实例尝试创建NewClass的实例。请注意,那时它尚未分配给变量newClass
  3. NewClass的新实例尝试创建JButton的新实例。为此,它首先需要访问BaseClass.myClass。不幸的是,对象BaseClass.myClass已经在内存中(它在当时正在初始化的过程中),但它尚未分配给BaseClass.myClass变量。所以它会产生NullPointerException。
  4. 因此,您需要将Button的初始化与BaseClass中myClass变量的初始化分开。

答案 1 :(得分:1)

  

我已经阅读了很多关于初始化的内容,但仍然没有找到内部类初始化的顺序。

类初始化是关于类静态字段的初始化和静态初始化程序块的执行。但是,Java中的内部类不允许具有任何静态字段或静态初始化程序。 (参见JLS 8.1.3。)因此内部类的(实际)类初始化没有实际意义。它发生时没有区别......因为内部类中没有任何东西可以初始化。

这里真正的问题是,当你有一个static字段时,它的实际初始化(到一个非空值)不会在静态初始化期间完成。相反,当代码的某些部分明确地调用BaseClass.main()时,发生。但是,您的代码都没有这样做......因此当您尝试使用myClass时,null将会{{1}}。

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