2012-07-22 156 views
0

嗯,我有一個最終屬性,但我不想在創建對象時初始化它,因爲我不能。於是,我就不能初始化它在我的構造函數,但使用二傳手,我猜它會一直像一個只,一次性使用的二傳手,但我有此錯誤:在對象實例化後初始化最終屬性

Test.java:27: error: cannot assign a value to final variable foo

this.foo = new String(foo); 

這裏是一個短我用來測試這個代碼:

class Test { 

    private final String foo; 

    public static void main(String[] args) { 
     Test test = new Test(); 
     test.setFoo("gygygy"); 
     System.out.println(test.getFoo()); 
    } 

    public Test() { 
     System.out.println("Constructor"); 
    } 

    public String getFoo() { 
     return foo; 
    } 

    public void setFoo(String foo) { 
     this.foo = foo; 
    } 

} 

所以我假設構造函數隱式地使this.foo = new String();或this.foo = null;我認爲我無法修改這種行爲,但我怎麼能等同於我想要做的?我認爲是這樣的:

private String foo; 

/* ... */ 

public void setFoo(String foo) { 
    if(!(this.foo.isInitialized())) 
     this.foo = foo; 
} 

但Object.isInitialized()方法顯然不存在,我無法找到一個相當於X)

因此,這裏是我的幾句話的問題:我能怎麼做 ?我想要一個最終屬性未在對象的實例化處初始化。

謝謝!

回答

2

您可以添加一個布爾場isInisialized但最好的選擇是在構造函數傳遞值(可能使用Builder模式如果需要)

+1

那麼我會簡單地使用布爾的解決方案,謝謝!我不知道建造者模式。我想我理解它是如何工作的,但我更喜歡第一種解決方案,它將以更快,更簡單的方式用於單個屬性:p – Thiht 2012-07-22 16:51:41

1

So here's my question in a few words : How can I do ? I want a final attribute that is not initialized at the instantiation of the object.

你根本無法做到這一點。所有你可以做的是有一個單獨的領域,你更新記錄,一旦你設置了「真實」字段 - 如果你嘗試再次設置它,拋出一個異常。

或者,讓你的類型不可變,但給它一個構造類的新實例的方法,其中除了單個新值之外,其餘的數據與以前相同。

public Test withFoo(String newFoo) { 
    // Call a private constructor here, passing in the other fields from 
    // "this", and newFoo for the value of foo 
} 
+0

這種方法可以被多次調用,所以它就好像我的屬性不是最終的,如果我沒有誤解 – Thiht 2012-07-22 16:57:32

+0

@Thiht:該方法將返回一個* new *對象...該字段將在構造函數中設置,因此它可能是最終的。 – 2012-07-22 17:32:18

+0

哦,好吧,我明白了。那麼,感謝這個答案,它也應該在這種情況下工作。 – Thiht 2012-07-22 18:29:03

0

規則說最終的實例成員變量應該在聲明它的地方或構造函數中進行初始化。通過這個規則,你的要求不能滿足你的代碼片段。您可以使用構建器模式來實現它。看到這個鏈接Builder Pattern in Effective Java