2012-08-09 23 views
1

我有以下查詢,我會通過Java不變類的概念,並提出瞭如下分析..對於不可改變的類

  • 所有字段必須是私有的,最好最後
  • 確保類不能被覆蓋 - 使課堂最後,或者使用靜態工廠,並保持建設者私人
  • 字段必須從構造/工廠進行填充
  • 不要爲字段提供任何setter方法
  • 注意收藏。使用Collections.unmodifiable *。
  • 此外,收藏應該只包含一個不可改變的對象
  • 所有干將必須提供不可變對象或使用保護性拷貝
  • 不提供改變對象的內部狀態的任何方法。

現在我有下面的類..

public final class Bill { 

    private final int amount; 
    private final DateTime dateTime; 
    private final List<Integers> orders; 

} 

請告知如何將它做成不可變類。

+2

並非所有這些技術上都是必需的 - 例如,'String.hashCode()'是懶散計算的,它的'hashCode'字段不是最終的,但是'String'即使如此也被認爲是不可變的。 – 2012-08-09 16:40:55

+0

>其hashCode字段不是最終的 這就是爲什麼提到這些字段是最好是最終的。只要它們不能通過外部消息傳遞給對象來修改,那麼這些成員就不是最終的,對嗎? – Vikdor 2012-08-09 16:46:55

回答

6

你的課堂是不變的。現在,你可能想添加一些方法:

public final class Bill { 

    private final int amount; 
    private final DateTime dateTime; 
    private final List<Integers> orders; 

    public Bill(int amount, DateTime dateTime, List<Integer> orders) { 
     this.amount = amount; //primitive type: ok 
     this.dateTime = dateTime; //joda.DateTime is immutable: ok 
     this.orders = new ArrayList<Integer> (orders); //make a copy as the caller could modify the list at its end 
    } 

    // no method that adds or removes from the list 

    public List<Integer> getOrders() { 
     return Collections.unmodifiableList(orders); //defensive copy 
    } 
} 

或者,你可以在構造函數中使用this.orders = Collections.unmodifiableList(orders);和getOrders()返回它:return orders;,這就加強了事實,你不應該修改該列表中,即使在你的班。

0

由於amount是一個值類型,所以datetime是不可修改的,如果您在其getter中返回Collections.unmodifiable()版本的orders屬性,則該類將變爲不可變的。

3

由於int是一種原始和DataTime(從JodaTime,我猜)是不可改變的,你需要做的唯一事情是要確保你使用一成不變的列表:

public final class Bill { 
    ... 
    public Bill(int amount, DateTime dateTime, List<Integer> orders) { 
     this.amount = amount; 
     this.dateTime = dateTime; 
     this.orders = Collections.unmodifiableList(orders); 
    } 
    ... 
} 

很明顯,你還需要一個構造函數來初始化final字段以及一些訪問該字段的方法。