web-dev-qa-db-ja.com

Dateオブジェクトを含むクラスを不変にする方法は?

これは、学術的な学習の観点からです。私が知っているのは、クラスを不変にしたいときはいつでも-最終的なプリミティブフィールドで構成されている必要があります-オブジェクトの構築中に参照がエスケープされない-他のオブジェクトを使用する場合、それらのオブジェクトも再帰的に不変であるか、API不変である必要がありますJava.lang.Stringのようなクラス、その他の詳細な見張り!

しかし、最近、面接官が候補者にJava.util.Dateを含む不変のクラスを作成するように依頼したという質問に遭遇しました。私の第一印象は、Dateオブジェクト自体ではなく、日付文字列を含むStringを使用して回避策を実行することはできますが、それは不可能であると言っています。

これについて私に明確にしてください。ありがとうございました。

8
xploreraj

クラスを不変にするためにここで行う最も簡単なことは、Dateオブジェクトの防御コピーを作成することです(構築パラメーターで渡される場合)。次に、セッターも提供しないでください。このように、クラス内のDateフィールドへの参照は、このクラス外のコードには表示されないため、Dateを変更することはできません。

必要なゲッター特性については、トムのコメントを参照してください。追加していただきありがとうございます。

(Date自体は変更可能であり、getterから返されたフィールドを変更すると、クラスのフィールドも変更されるため、Getterはdateフィールドのコピーも返す必要があります。)

詳細と詳細については: http://www.informit.com/articles/article.aspx?p=31551&seqNum=2

17
DrunkenPope

使用している日付の前後にラッパークラスを作成し、実際に値を変更できるセッターやメソッドを提供しないことをお勧めします。

不変にするためには、次のことを考慮する必要があります。

  1. クラスがオーバーライドできないことを確認する必要があります-最終として作成します。
  2. すべてのフィールドをプライベートおよびファイナルにします。
  3. インスタンス変数を変更するセッターやメソッドを提供しないでください。
  4. 呼び出し先と呼び出し元の間でオブジェクトを防御的にコピーします。

    詳細については このチュートリアル を検討してください

5
shikjohari

1)「セッター」メソッドを提供しないでください。

2)すべてのフィールドを最終的かつ非公開にする

3)サブクラスがメソッドをオーバーライドすることを許可しない-クラスをfinalとして宣言する

4)可変インスタンス変数の場合-Ex date:この場合、特別な注意を払う必要があります。

5)コンストラクターをプライベートにし、ファクトリメソッドでインスタンスを構築します。オブジェクト作成ロジックを1か所に格納するファクトリメソッド。

   public static MyImmutableClass createNewInstance(Integer fld1, String fld2, Date date)
{
    return new MyImmutableClass (fld1, fld2, date);
}

6)代わりに、コンテンツがコピーされた新しいDateオブジェクトを返す必要があります。

public Date getDateField() {
    return new Date(dateField.getTime());
}

-ここで、dateFieldは、プライベートコンストラクター内に設定されるフィールドです。

0
yashwantD