2014-09-01 93 views
0

我有這段代碼,編譯器的返回值爲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 
    }               
} 
+3

當你調用嵌套實例類構造函數時,我猜'BaseClass'的靜態字段'myClass'是'null'。 – Mena 2014-09-01 12:16:42

+0

什麼是'BaseClass',我認爲myClass應該是'static'。當您嘗試使用調試器來調試程序時,您會看到什麼? – 2014-09-01 12:27:02

+0

myClass是靜態的。可能Mena所說的是這種情況,有沒有辦法告訴初始化方法在某個級別停止,並讓BaseClass中的值分配首先發生? – 2014-09-01 12:28:01

回答

1

我讀過很多關於初始化,但仍然還沒有被初始化什麼順序內部類碰到過。

類初始化是關於類靜態字段的初始化和靜態初始化塊的執行。但是,Java中的內部類不允許有任何靜態字段或靜態初始化程序。 (見JLS 8.1.3。)因此,內部類的(實際)類初始化是沒有意義的。它發生時沒有什麼區別......'因爲內部類沒有什麼東西可以初始化。

這裏真正的問題是,當你有一個static領域,其實際的初始化(一個非空值)沒有靜態初始化期間完成。相反,它會發生當代碼明確電話BaseClass.main()的某些部分。然而,你的代碼沒有這樣做......因此myClass將在您嘗試使用它時將是null

再次......我強調......這不是靜態初始化如何工作的問題,因爲您的代碼不使用靜態初始化來初始化有問題的字段。

+0

我認爲實例的值賦值是在實例進行其他調用之前發生的,但我看到現在有多愚蠢。因此,MyClass的初始化操作幾乎是不可能的。儘管尋找解決方法並不困難。感謝您的回答。 – 2014-09-01 13:41:59

1

這裏是發生了什麼:

  1. 基類嘗試創建MyClass的實例。請注意,當時它尚未分配給myClass,但
  2. MyClass的新實例嘗試創建NewClass的實例。請注意,當時它沒有分配給變量newClass,但NewClass的新實例試圖創建一個新的JButton實例。爲此,它首先需要訪問BaseClass.myClass。不幸的是,對象BaseClass.myClass已經在內存中(它正在進行初始化),但它尚未分配給BaseClass.myClass變量。所以它會產生一個NullPointerException。

因此,您需要將Button的初始化與BaseClass中myClass變量的初始化分開。

+0

是的,我現在看到問題了,謝謝。 – 2014-09-01 13:32:49