2012-10-23 39 views
4

靜態最終變量我想basicly是這樣的:設置在構造

public class Test 
{  
    private static final Integer a; 

    public Test(Integer a) 
    { 
     this.a = a; 
    } 

}

這顯然是行不通的,導致第二創建的實例會嘗試重寫最後一個變量。 那麼有沒有辦法通過構造函數爲所有實例賦予相同的不可變值?

+0

它是'static final',所以它是所有時間創建的,永遠不會改變。爲什麼構造函數是一個合理的地方呢?(如果這是由於懶惰評估它的願望,你可能會使它不是最終的,並依靠它的私有訪問控制來防止濫用。) –

+0

它在構造函數中,因爲值取決於配置文件的值,但不應該'一旦設置就不會改變。 –

+0

這聽起來像你應該讓這個領域不是靜態的。 –

回答

11

靜態最終值應該在靜態上下文中初始化,而不是由實例初始化。

一個選項是在聲明設定值:

private static final Integer a=FileConfig.getInstance().getA(); 

每個類都可以具有靜態{}塊,其中代碼被調用以初始化類的靜態部分。

static { 
    a = FileConfig.getInstance().getA(); 
} 

最後,你可以從一個靜態方法

private static int getA() { 
    return FileConfig.getInstance().getA(); 
} 

private static final Integer a=getA(); 

在封閉的設定值,靜態實例的初始化不實例構造屬於。

如果配置值有時會改變,那麼根本沒有理由將值a存儲在靜態最終變量中。如果您想在構造函數中使用常量a創建每個實例,首先需要靜態字段的目的是什麼?不知何故,當你第一次調用構造函數時,你傳入的值是某處。如果該值應該是靜態的並且是最終的,那麼可以從靜態初始化程序中獲取它。如果配置不是單例,但每個實例始終產生相同的a值,則可以輕鬆地執行a = new FileConfig().getA();

除此之外,您可以將該值設置爲非最終值,並放心,因爲您總是將相同的值放入a,所以靜態變量不會改變。

但是,您可以使a成爲該類的最終實例變量,在構造函數中設置。

+0

但是這個值在編譯時並不知道,它來自一個讀取配置文件的類,因此我需要一種將它傳遞給Test類的方法。 –

+0

爲什麼沒有靜態方法只需要從配置文件讀取類的值?它應該在啓動時可用,並且靜態初始化方法將愉快地阻塞,同時配置讀取器類加載它的值。我編輯了我的例子。 –

+0

讀取configfiles的類不是單例,也不具有靜態字段/方法,所以很遺憾,這不是一個解決方案:( –

2

那麼有沒有辦法通過構造函數爲所有實例賦予相同的不可變值?

我假設你想要的值被分配到a首次創建Test類型的對象,但沒有創建任何後續實例時。在這種情況下,你不能聲明它finala最初將爲空,構造函數必須檢查它是否爲空並在此情況下爲其分配值。

但我希望你看看設計,特別是爲什麼來電者必須提供價值。在第二個Test對象創建後Test.a在以下情況下不會改變嗎?

// assume this is the first `Test` object created: 
Test t = new Test(5); // Test.a is 5 
Test t = new Test(6); // Test.a is *still* 5