4

インタビューの1つで、「文字列を不変にする方法」を尋ねられました。答えがわからなかったので返事をしませんでした。後でインタビュアーに同じことを聞いた。答えは、文字列クラスが最終的なものであり、それが不変性を実現する方法です。

それは正解ですか?はいの場合、StringBufferでさえ最終クラスとしてマークされます。では、なぜStringBufferは不変ではないのでしょうか。

4

7 に答える 7

11

以下の組み合わせです。

  1. フィールドはプライベートであるため、直接変更することはできません。
  2. setメソッドは提供されていないため、間接的に変更することもできません。
  3. Stringis final- したがって、可変性 (つまり、セッターなど) を追加することはできません。
于 2013-02-11T13:51:42.580 に答える
4

いいえ、それは正しい答えではありません。String は、内部コンテンツを変更する方法を提供しないため、不変性を実現します。したがって、String オブジェクトをインスタンス化し、参照を割り当てることはできますが、初期化後に内容を変更することはできません。

于 2013-02-11T13:52:09.163 に答える
3

文字列は不変オブジェクトです。

次のガイドラインに従って、クラスを不変にします。

  • クラスをオーバーライドできないようにする
  • クラスfinalを作成するか、静的ファクトリを使用してコンストラクタを非公開にします
  • フィールドprivateを作り、final
  • setXXXメソッドだけでなく、クラスに変更可能なオブジェクトフィールドがある場合に状態を変更できるメソッドは、何らかの方法でオブジェクトの状態を変更できるメソッドを提供しないでください。発信者
  • メソッドへの後続の呼び出しと組み合わせて引数のないコンストラクターを使用するのではなく、単一のステップでオブジェクトを完全に構築するように呼び出し元に強制しsetXXXます (つまり、Java Beans 規則を回避します)。
于 2013-02-11T13:59:14.563 に答える
2

finalキーワードは不変性と同じではありません。ユーザーがコンテンツをString変更できるようにするメソッドを定義していないため不変であり、最終的なものであり、サブクラス内のものを変更する可能性を排除します。

Listインスタンス変数 finalのようなものを作成しても、その内容を変更して変更可能にすることができます。

于 2013-02-11T13:53:20.030 に答える
1

最終的であるということは、派生できないことを意味します。それは不変性を与えません

不変性はカプセル化によって達成され、内部に保持されている文字配列を修正する手段を提供しません。つまり、内部フィールドを変更するメソッドはありません。

于 2013-02-11T13:54:32.323 に答える
0

クラスを不変にする通常の方法は、次のことを確認することです。

  • すべてのフィールドはプライベートです。
  • 構築後にフィールドを変更する方法はありません。
  • これは最終的なものです(拡張機能が不変性を壊さないようにするため)。

文字列は、少なくともSun / Oracleの実装では、実際にはこの手順に従わないという点で少し特殊です。実装には、オブジェクトのハッシュコードをキャッシュする可変フィールドがあります。したがって、オブジェクトの内部状態を変更するメソッド(hashCode)がありますが、この状態の変更によってオブジェクトの動作が変更されることはありません。以降の呼び出しはhashCodeより高速に実行されますが、結果に違いはありません。

于 2013-02-11T14:21:11.213 に答える
0

最初は空である文字列のプールは、クラス String によってプライベートに維持されます。

String の JavaDoc を参照してください。 public native String intern();

見る:

于 2013-02-11T13:54:28.707 に答える