インタビューの1つで、「文字列を不変にする方法」を尋ねられました。答えがわからなかったので返事をしませんでした。後でインタビュアーに同じことを聞いた。答えは、文字列クラスが最終的なものであり、それが不変性を実現する方法です。
それは正解ですか?はいの場合、StringBufferでさえ最終クラスとしてマークされます。では、なぜStringBufferは不変ではないのでしょうか。
インタビューの1つで、「文字列を不変にする方法」を尋ねられました。答えがわからなかったので返事をしませんでした。後でインタビュアーに同じことを聞いた。答えは、文字列クラスが最終的なものであり、それが不変性を実現する方法です。
それは正解ですか?はいの場合、StringBufferでさえ最終クラスとしてマークされます。では、なぜStringBufferは不変ではないのでしょうか。
以下の組み合わせです。
set
メソッドは提供されていないため、間接的に変更することもできません。String
is final
- したがって、可変性 (つまり、セッターなど) を追加することはできません。いいえ、それは正しい答えではありません。String は、内部コンテンツを変更する方法を提供しないため、不変性を実現します。したがって、String オブジェクトをインスタンス化し、参照を割り当てることはできますが、初期化後に内容を変更することはできません。
文字列は不変オブジェクトです。
次のガイドラインに従って、クラスを不変にします。
final
を作成するか、静的ファクトリを使用してコンストラクタを非公開にしますprivate
を作り、final
setXXX
メソッドだけでなく、クラスに変更可能なオブジェクトフィールドがある場合に状態を変更できるメソッドは、何らかの方法でオブジェクトの状態を変更できるメソッドを提供しないでください。発信者setXXX
ます (つまり、Java Beans 規則を回避します)。final
キーワードは不変性と同じではありません。ユーザーがコンテンツをString
変更できるようにするメソッドを定義していないため不変であり、最終的なものであり、サブクラス内のものを変更する可能性を排除します。
List
インスタンス変数 finalのようなものを作成しても、その内容を変更して変更可能にすることができます。
最終的であるということは、派生できないことを意味します。それは不変性を与えません
不変性はカプセル化によって達成され、内部に保持されている文字配列を修正する手段を提供しません。つまり、内部フィールドを変更するメソッドはありません。
クラスを不変にする通常の方法は、次のことを確認することです。
文字列は、少なくともSun / Oracleの実装では、実際にはこの手順に従わないという点で少し特殊です。実装には、オブジェクトのハッシュコードをキャッシュする可変フィールドがあります。したがって、オブジェクトの内部状態を変更するメソッド(hashCode
)がありますが、この状態の変更によってオブジェクトの動作が変更されることはありません。以降の呼び出しはhashCode
より高速に実行されますが、結果に違いはありません。
最初は空である文字列のプールは、クラス String によってプライベートに維持されます。
String の JavaDoc を参照してください。
public native String intern();
見る: