14

Java のすべての最終クラスは不変です。String と Integer はどちらも最終クラスであり、どちらも不変です。

4

8 に答える 8

30

いいえ、final はクラスを拡張できないことを意味します。可変性については何も言いません。例えば:

final class MutInt {
   public int modifyMe;
}
于 2009-10-27T11:57:01.980 に答える
22

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

public final class FinalMutable {
  int value;
  public void setValue(int v) { value=v; }
  public int getValue() { return value; }
}
于 2009-10-27T11:57:31.740 に答える
9

不変性のキーワードはなく、デザイン パターンのようなものです。

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

紛らわしいのはこれです: final キーワードは、クラスで使用される場合と、フィールド/変数で使用される場合とで異なる意味を持ちます。前者は「このクラスは拡張できない」という意味です。2 つ目は、「この変数 (または参照) は変更できない」という意味です。

于 2009-10-27T11:58:51.210 に答える
5

前に他の人が言ったfinalように、Java でクラスを不変にすることはありませんが、不変性戦略の一部を果たします。不変性を得るには、一般的なガイドラインに従う必要があります。

  • クラスをオーバーライドできないようにする - クラスを作成するfinalか、静的ファクトリを使用してコンストラクタを非公開にします
  • フィールドprivateを作り、final
  • メソッドへの後続の呼び出しと組み合わせて引数のないコンストラクターを使用する代わりに、呼び出し元に単一のステップでオブジェクトを完全に構築するように強制しsetXXXます (つまり、Java Beans 規則を回避します)。
  • setXXXメソッドだけでなく、状態を変更できるメソッドを提供しないでください。
  • クラスに変更可能なオブジェクト フィールドがある場合は、クラスとその呼び出し元の間で渡されるときに防御的にコピーする必要があります。
于 2009-10-27T15:46:47.583 に答える
5

他の応答に加えて、 のコードをjava.lang.String見ると、 field: が含まれていることがわかります。hashこれは変更可能hashCode()で、実際には が初めて呼び出されたときに計算および保存されます。

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

また、JDK 内の一般的なアプローチは、変更を許可せずにオブジェクトの内部状態を公開するために使用できる不変ラッパーの実装であることに気付くかもしれません。例えば

private final List<String> values;

public List<? get String> getValues() {
  return Collections.unmodifiableList(values);
}
于 2009-10-27T12:09:34.987 に答える
2

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

于 2011-07-26T16:25:40.100 に答える
0

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

于 2012-06-05T07:58:16.247 に答える