2014-04-12 65 views
3

在下面的代碼中,數據字段初始化的順序是什麼?數據成員和成員函數的java遵循的一般規則是什麼?Java中數據字段的初始化順序

public class TestClass 
{ 
    int j=10; 
    static int h=5; 

    public static void main(String[] args) 
    { 
    TestClass obj= new TestClass();  
    } 
} 

回答

3

一般來說:

1)靜態字段構件(一般靜態初始化)

2)非靜態字段成員

3)構造

但是可以用這樣的代碼片段測試它:

public class TestClass { 
    int i = 10; 
    static int j = 20; 
    public TestClass() { 
     // TODO Auto-generated constructor stub 
     System.out.println(i); 
     i = 20; 
     System.out.println(i); 
    } 
    public static void main(String[] args) { 
     new TestClass(); 
    } 
} 

從偉大的「思考在Java中的」加引號:

在類,初始化的順序是由爲了使變量的類中定義 確定。變量定義可能分散在整個方法定義中,也可能分佈在方法定義之間,但變量在調用任何方法之前被初始化,即使是構造函數也是如此。 ................................... 靜態只有一個存儲單元,不管創建了多少個對象。 您不能將靜態關鍵字應用於局部變量,因此它僅適用於字段。如果一個字段是一個 staticprimitive並且您沒有初始化它,它將獲得它的類型的標準初始值。如果它是 對對象的引用,則默認初始值爲null。


總結creatingan對象的過程中,考慮一個名爲Dog類:

  1. 即使它沒有明確使用static關鍵字,構造函數實際上是一個 靜態方法。因此,第一次創建Dog類型的對象時,或者第一次訪問類Dog的靜態方法或靜態字段時,Java解釋器必須通過搜索類路徑來找到Dog.class。

  2. 隨着Dog.class的加載(創建一個Class對象,你將在後面瞭解到),其所有的 都會運行它的靜態初始值設定項。因此,靜態初始化只發生一次,因爲第一次加載了類對象。

  3. 當您創建一個新的Dog()時,Dog對象的構造過程首先爲堆對象上的Dog對象分配足夠的存儲空間 。

  4. 這種存儲擦拭爲零,在狗 對象中的所有原語自動設置爲默認值(零號,等效於布爾和 焦炭)和引用爲null。

  5. 執行在字段定義處發生的任何初始化。

  6. 構造函數被執行。這可能實際上涉及相當數量的活動,特別是涉及到繼承時。

1

這是訂單。

  1. 靜態字段初始化和靜態塊在類加載時執行,它們將按照它們聲明的相同順序進行初始化。
  2. 設置字段默認初始值(0,假,空)
  3. 調用構造函數對象(但不執行構造函數體還)
  4. 調用父類
  5. 的構造初始化使用初始化和初始化塊
  6. 執行構造
+0

我喜歡你的完整性。鑑於此,你已經錯過了靜態初始化塊。 – tom

+0

@tom,答覆已更新 –

0

我認爲你只是缺少JLS,其中包括section 12.4.2的身體字段:

接下來,按照文本順序執行該類的類變量初始值設定項和靜態初始值設定項或接口的字段初始值設定項,就好像它們是單個塊一樣。

「在文本順序」部分是重要的一點。

如果將m從靜態變量更改爲實例變量,那麼該字段將不會通過類初始化進行初始化 - 它只會通過實例初始化(即構建實例時)進行初始化。目前,這會導致堆棧溢出 - 創建一個實例都需要創建另一個實例,它需要創建另一個實例等

所以最後下面是令您正在搜索:

初始化塊按照它們出現在程序中的順序運行。 靜態初始化塊在類首次加載到JVM時運行 只要創建了新的類實例,就會運行實例初始化塊。