2011-10-27 33 views
0
參數的構造函數(S)內初始化最終參考
import java.util.*; 

public Class C 
{ 
    final Vector v; 
    C() 
    { 
      v=new Vector(); 
    } 

    C(int i) 
    { 
      //Here, it is an error. v might not have been initialized. 
    } 

    public void someMethod() 
    { 
      System.out.println(v.isEmpty()); 
    } 

    public static void main(String[] args) 
    { 
      C c=new C(); 
      c.someMethod(); 
    } 
} 

上面的代碼是一個編譯時錯誤。我知道,但它說(在NetBeans中)變量v應該被初始化。當我在重載的構造函數中初始化它時,它修復了這個問題並打印出「true」。我的問題是爲什麼我應該在重載版本的構造函數中重新初始化它(我已經在默認構造函數中初始化了它),我甚至沒有使用重載版本。爲什麼?需要在Java

+0

一種可能性是將其更改爲最終Vector v = new Vector();'。那麼你將不必在構造函數中編寫它。 – Vlad

+0

這是太正確了,弗拉德,但它不會讓v稍後被初始化,因爲它是最終成員,如果需要的話。 – Bhavesh

+1

如果你通過構造函數來做同樣的事情。如果你需要重新分配它,或者如果你不想初始化構建矢量,那麼它不是最終的。 – Vlad

回答

4

當您創建一個新對象時,只會調用您的類的構造函數中的一個來初始化該對象。你似乎認爲所有的構造函數都被調用,或者總是調用默認的(無參數)構造函數。事實並非如此。

所以,每個構造函數都需要初始化所有的成員變量final

請注意,從一個構造函數中,您可以使用this(...)明確地調用另一個構造函數。例如,作爲C(int i)構造函數的第一行,可以添加一行:this();以調用C()構造函數。另一種解決方案是在該行,你聲明它初始化成員變量:

public class C { 
    // v will be initialized, no matter which constructor will be used 
    final Vector v = new Vector(); 

    C() { 
    } 

    C(int i) { 
     // ... 
    } 

    // ... etc. 
} 

注意,你並不需要顯式初始化非final成員變量;如果你沒有初始化它們,Java將使用默認值對它們進行初始化(對於非基元類型變量,這是null)。但是,您確實需要明確初始化final成員變量。

另一個注意事項:Vector是一個遺留集合類。您應該更喜歡使用ArrayList

第三個注意:使用泛型使您的代碼更安全。例如,如果您需要將字符串存儲在列表中,請使用ArrayList<String>而不是原始類型ArrayList

5

因爲重載的構造函數不會調用默認的構造函數。使用this()來調用它。

+0

+1 - 還有'v'被聲明爲final的事實。如果它不是最終的,那麼它會很好(沒有編譯錯誤)。 – CoolBeans

1

重載的構造函數不調用其他的版本,除非你明確地

this(); 

這可能是你想做的事情去做。