2015-07-01 47 views
3

我正在嘗試修復下面的類,因此將成爲不可改變的:是否可以修復這個類,使之永恆

public class ImmutableList<E> implements Iterable<E> { 
    private List<E> internal; 
    public ImmutableList(List<E> l) { 
     this.internal = l; 
    } 
    public int size() { 
     return this.internal.size(); 
    } 
    public E get(int i) { 
     return this.internal.get(i); 
    } 
    public Iterator<E> iterator() { 
     return this.internal.iterator(); 
    } 
} 

但此刻我不是成功的,我的問題是,我不知道E的類型,所以我不知道如何深度複製它。 我想知道是否有可能使該類不可變?

在此先感謝

+0

'new ArrayList (l)'?當然,這仍然不會使它不可變,因爲'iterator()'可以用來改變基礎列表,但不知道'E'類型根本不是問題。但是至於深拷貝'E',那不會發生。通過防禦副本和'iterator()'修復,您可以使您的類有條件地不可變,條件是'E'必須是不可變的。 – biziclop

+0

所以,如果我理解它是正確的,我可以「保護」內部列表,但是我不能讓這個類完全不可變,只要我不確定E是不可變的還是不可變的? –

+0

正確。但這超出了班級的控制範圍,你不應該關心它。重要的是,沒有人可以篡改你可以控制的班級內部狀態。 – biziclop

回答

3

你的類是幾乎「作爲永恆不變的越好。」沒有完全通用的方法來處理任意的泛型類型,所以你不應該擔心它。

兩個遺留問題:

  • 你需要複製l - 淺拷貝就足夠了。 this.internal = new ArrayList<E>(l)會做。
  • 如果internal.iterator()支持remove(),那麼您的列表類型的消費者可以刪除元素。
  • 讓你的課final,所以它不能以可變的方式分類。
+3

由於構造函數沒有製作防禦性副本,因此它不會盡可能不變。 – biziclop

+0

好抓,固定。 –

+3

另外,它不應該是最後一堂課嗎?否則,我可以說,重寫構造函數,保存'l'並且它會再次變化。 – blalasaadri