2012-06-18 35 views
2

奇怪,但我找不到這個問題的重複。 我有一個超類overrideMe()方法和一個覆蓋它的子類。 在調用子類構造函數之前,最終字段是否真正初始化? 正如我從輸出中看到的那樣。子類中的最終字段初始化

下面是輸出: 超類構造 STR值:someValue中 子類構造 STR值:someValue中

可否請你給我講解一下? 我認爲實例變量是在構造函數調用中初始化的,但不是在它之前。

下面的代碼:

public class Test { 
    public Test() { 
    System.out.println("Superclass constr"); 
    overrideMe(); 
    } 

    public void overrideMe() { 
    } 
} 

class Ext extends Test { 
    private final String str = "someValue"; 

    public Ext() { 
    System.out.println("Subclass constr"); 
    } 

    @Override 
    public void overrideMe() { 
    System.out.println("str value: " + str); 
    } 

    public static void main(String[] args) { 
    Ext test = new Ext(); 
    test.overrideMe(); 
    } 
} 

編輯: 如果我declasre STR場非最終,它在構造函數中調用子類返回null如我所料。

+0

每個構造函數都會先調用'super'(或'this'調用'super'),這樣超類始終會被初始化。 (除了沒有超類的'java.lang.Object') –

回答

2

是在構造函數被調用之前初始化字段,並且這個字段在超載之前從上層類開始。

這裏是一個一般性介紹:http://www.linuxtopia.org/online_books/programming_books/thinking_in_java/TIJ306_014.htm

+2

[JLS 7](http://docs.oracle.com/javase/specs/jls/se7/html/jls-12.html#jls-12.5)爲更清楚 –

+0

糟糕,這是一個非常愚蠢的問題:) 我仍然不能得到的唯一的事情是爲什麼最終字段不初始化爲null。 – iozee

+0

@iozee決賽場永遠不會改變。它無法在null處初始化並在此之後更改值。 –

1

與初始化最後一個字段將與由編譯器的常量字符串來代替,這就是爲什麼它似乎是超級構造函數返回即使前場被初始化。

如果最後一個字段是空白的inited,這意味着它是在子類的構造函數中插入的,那麼超級構造函數當然會看到一個null。

如果該字段既不是最終的也不是靜態的,並且提供了初始化程序,則它將在超級構造函數之後和子構造函數之前進行插入。