2009-06-19 4 views
1

JavaのStringクラスと同様に、不変クラスを構築するための効率的な方法を探しています。オブジェクトを不変にする方法がありません

+0

文字列のようなクラスを探していますか?私は最初にあなたの質問を読んでいませんでしたが、もしあなたがそうしたら、私はいくつかのString固有の例で私の答えを変えます。 – Jorn

+0

文字列はJavaの特別な市民です。まさにプリミティブ型ではありませんが、クラスとはみなされません。 Stringは、+演算子をオーバーロードする唯一の "クラス"です。 2つのストリングを追加すると、新しいストリングになります。演算子のオーバーロードは通常のクラスでは許可されません。 – kgiannakakis

+0

文字列をクラスと見なすことはできませんか? –

答えて

8
  1. すべてのフィールドは privateことができ、好ましくはfinal
  2. クラスは をオーバーライドすることはできませんことを確認しなければならない - プライベート
  3. たフィールドから移入されなければならない、クラスの決勝を行い または静的ファクトリを使用して コンストラクタを保ちます コンストラクター/ファクトリー
  4. フィールドにはセッターを指定しないでください。
  5. コレクションに気を付ける。 Collections.unmodifiable*を使用してください。また、コレクションはすべてゲッターが 不変オブジェクトを提供したり、 オブジェクトの内部状態を変更 任意のメソッドを提供しないでくださいdefensive copying
  6. を使用しなければならない唯一の不変オブジェクト
  7. が含まれている必要があります。

Tom Hawtinfinalは任意であることが指摘されている。 Stringclassには、キャッシュhashがあります。これは、ハッシュ関数が呼び出されたときにのみ割り当てられます。

+0

Sun String実装にはfinalではないインスタンスフィールドがあります。 –

+0

良い点。 「最終的な」要件ではありません。 Stringのハッシュvarは完全な例です。 –

+0

派生クラスが保護されたフィールドを公開していないことを確実にするためにfinalをmakeにすることも考えてください。 –

1

フィールドのいずれも変更できない場合、オブジェクトは不変です。したがって、フィールドはfinalである必要があります。オブジェクトをサブクラス化したくない場合は、Stringと同様にクラス自体をfinalにすることができます。あなたは途中である - は簡単に多くの情報を持つ不変オブジェクトを構築するために、あなたは、コンストラクタを使用して、すべてのフィールドを移入し、フィールドが最終作る場合Wikipedia

+0

もし彼がサブクラスを望んでいなければ、クラス自体を最終的にするべきです。 –

+0

良い点、私はそれを追加します。 – Jorn

1

を参照してください、詳細についてはFactory Pattern

をご覧くださいそこ。

フィールドにカスタムタイプが使用されている場合は、それらも変更不可能にする必要があります。

コレクションであるフィールドはすべて、変更不可能なコレクションを使用する必要があります。安全な側にする必要があります。

オブジェクトグラフについて心配する必要があります。

オブジェクト上の任意のメソッドは、最終的でないフィールドに注意する必要があります。例えば。 String.addは新しい文字列を作成します。 1つのフィールドを変更する必要がある場合は、コピーコンストラクタを使用します。

最後にオブジェクトを最終的にします。

+0

例の助けを借りてこれを説明できるかどうか本当に感謝します。 –

+0

まだコピーをお持ちでない場合は、Josh BlochのEffective Javaのコピーを入手してください。彼は私が今まで以上にこれを説明する! – Fortyrunner

+0

確かに、それは今日それ自体を行うでしょう。ありがとう –

関連する問題