2009-10-27 9 views

答えて

22

いいえ - 最終的なクラスは、そのクラスから継承できないことを意味します。それは可変性とは関係ありません。次のクラスは最終的には変更可能です:

public final class FinalMutable { 
    int value; 
    public void setValue(int v) { value=v; } 
    public int getValue() { return value; } 
} 
+2

したがって、クラスを不変にするためには、メソッドをインスタンス化し、インスタンス変数(この場合は "value")をfinalにします。 私は正しいです.. ?? – Gourav

+1

はい、セッターを破棄して「値」を確定させる必要があります。 –

+1

それに加えて、Rytmisは以下の点を参考にしています。値が変更可能なオブジェクトであれば、あなたのオブジェクトは本当に不変ですか?最高の価値を秘密にし、防御的なコピーを行うためにgetValueを変更してください。 –

30

いいえ、最終的にクラスを拡張できないことを意味します。それは変異性について何も言わない。例:

final class MutInt { 
    public int modifyMe; 
} 
9

不変性のためのキーワードはありません。それはデザインパターンのようです。

編集:
これは、クラスを不変にするキーワードがないことを意味します。クラスを不変にするには、内部または外部を最終的または個人的に保護する必要があります。

混乱することは次のとおりです。最終キーワードは、クラスで使用されたときに異なる意味を持ち、フィールド/変数で使用されたときに異なる意味を持ちます。前者は「このクラスは拡張できません」という意味です。第2の意味は「この変数(または参照)は変更できません」を意味します。他の回答にさらに

+3

フィールドと変数の "最終的な"キーワードがあります - しかし、それはオブジェクトを不変にしません。 – Rytmis

+0

@Rytmis:そうですが、java.lang.Stringのようにクラスを不変にするkeyowrdはありません。私はこれをもっと明確にするために答えを編集します。 –

+1

また、フィールド上での 'final'の使用は、Javaメモリモデル(1.5以降)の特定のセマンティクスでオーバーロードされています。 – Grundlefleck

5

あなたがjava.lang.Stringためのコードを見れば、あなたはそれがフィールドが含まれ表示されます:hash可変あり、実際に計算され、hashCode()が初めて呼び出されたときに保存されています。

ただし、クラスはまだ不変です。hashフィールドは直接アクセスすることも、クラス外で変更することもできません。

また、オブジェクトの内部状態を変更せずに公開するために使用できる不変ラッパーの実装は、JDK内で一般的なアプローチになります。例えば

private final List<String> values; 

public List<? get String> getValues() { 
    return Collections.unmodifiableList(values); 
} 
+0

そして、スレッド安全性のために重要なのは、ハッシュフィールドの遅延割り当ては*良性*データ競合です。そうでなければ、異なるスレッドのhashCode()の2人の呼び出し元は、2つの異なる値を見ることができます。 – Grundlefleck

5

それは不変性戦略の一翼を担っているもののfinalは、Javaのクラスimuutableをしない前に、他の人が言ったように。不変性を得るために、あなたは一般的な義務づける方針に従う必要があります。

  • をクラスがオーバーライドすることはできませんことを確認 - クラスfinalを作る、または静的なファクトリを使用し、プライベートコンストラクタを保つ
  • にフィールドprivatefinal
  • 力の発信者を作ります後でsetXXXメソッドを呼び出す(つまり、Java Beansのコンベンションを避ける)引数なしのコンストラクタを使用する代わりに、オブジェクトを単一のステップで完全に構築します(つまり、Java Beansのコンベンションは避けてください)。
  • objecの状態を変更できるメソッドはありませんどのような方法でのトン - だけではなくsetXXX方法が、クラスは、任意の可変オブジェクトのフィールドを持っている場合、クラスとその呼び出し元
+0

+セキュリティマネージャを追加するリフレクションを使用してアクセシブルフラグを変更しないようにしてください! –

+1

もう1つのこと:コンストラクタ内の可変引数の守備コピーを作成してください。これはEffective Java、2nd Ed。、item#15でカバーされています。 –

+0

Ahhはいアイテム#15-> 5を探しましたが、実際のポイントはコンストラクタのアイテム#39と 'readObject'メソッドのアイテム#76です –

2

ザ・間を通過したときに、その後、彼らは守備コピーしなければならない状態

  • を変更することができます任意の方法プライベートフィールドは、サブクラスのオーバーライドされたメソッドによってアクセスすることはできません...したがって、サブクラスメソッドがスーパークラスのプライベートフィールドを変更する方法はありません...次に、不変クラスをfinalとして使用することは何ですか?

  • 0

    最終的なキーワードは、他のクラスがそれを継承するのを防ぎます。最終的なキーワードでは不変ではありませんが、インスタンスクラスのメンバーを非公開にする、セッターを使用しないでゲッターを使用するなどの条件があります

    関連する問題