1

私は次のクエリを持っています、私はJava不変クラスの概念を調べていて、次の分析を思いつきました。

  • すべてのフィールドはプライベートで、できれば最終的なものでなければなりません
  • クラスをオーバーライドできないようにする-クラスをfinalにするか、静的ファクトリを使用してコンストラクタをプライベートに保つ
  • フィールドはコンストラクタ/ファクトリから入力する必要があります
  • フィールドにセッターを提供しないでください
  • コレクションに気をつけてください。Collections.unmodizable*を使用します。
  • また、コレクションには不変オブジェクトのみを含める必要があります
  • すべてのゲッターは不変オブジェクトを提供するか、防御コピーを使用する必要があります
  • オブジェクトの内部状態を変更するメソッドを提供しないでください。

今、私は次のクラスを持っています。

public final class Bill {

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

}

不変クラスとして作成する方法を教えてください。

4

3 に答える 3

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;もできます。これにより、クラス内であっても、そのリストを変更してはならないという事実が強制されます。

于 2012-08-09T16:43:09.780 に答える
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フィールドを初期化するためのコンストラクターと、そのフィールドにアクセスするいくつかのメソッドも必要です。

于 2012-08-09T16:42:38.430 に答える
0

金額は値型であるため、日時は変更できません。getterでorders属性のCollections.unmodizable()バージョンを返すと、クラスは不変になります。

于 2012-08-09T16:42:23.413 に答える