1. ホーム
  2. java

new String()」もイミュータブル?

2023-10-22 14:05:20

質問

Java Stringを勉強しているものです。以下の質問は、以下の投稿に基づくものです。

Java Stringは特殊です。

Javaにおける文字列の不変性

  1. 不変性です。 さて、不変性ということで、String クラスは 共通プール の値が他の場所や変数で再利用できるように設計されています。これは、もし String として作成された場合

    String a = "Hello World!"; しかし、次のような文字列を作成すると

    String b = new String("Hello World!"); のような文字列を作った場合、なぜこれもイミュータブルになるのでしょうか?(あるいはそうなのか?)です。これは専用のヒープメモリを持っているので、他の変数に影響を与えることなくこれを変更することができるはずです。ということは、設計上、他の理由があって String は全体として不変であると考えられているのでしょうか?それとも、私の上記の仮定は間違っているのでしょうか?

  2. 2つ目にお聞きしたかったのは 共通文字列プール . もし私が文字列オブジェクトを

    String c = ""; という文字列オブジェクトを作成すると、プール内に空のエントリが作成されますか?

これらに関する投稿はすでにありますか?もしそうなら、誰かリンクを教えてください。

どのように解決するのですか?

new String() を生成する式である。 String ... と String はどのように生成されても不変です。

(もし new String() が変更可能かどうかを尋ねることは無意味です。 それはプログラムコードであり、値ではありません。 しかし、私はそれがあなたが本当に意味するものではないことを取ります)。


もし、文字列オブジェクトを String c = ""; という文字列オブジェクトを作成すると、プールに空のエントリが作成されますか?

はい。つまり、空の文字列のためのエントリが作成されます。空文字列のエントリーは何も特別なことはありません。 String .

(衒学的に言えば、プールエントリの "" のプールエントリはコードが実行されるずっと前に作成されます。 実際には、コードがロードされたときに作成されます ... あるいはそれよりも早いかもしれません)。


だから、私は新しいヒープオブジェクトが同様に不変であるかどうかを知りたいと思った、....

はい、そうです。 しかし、イミュータビリティはStringオブジェクトの基本的な性質です。 すべて String オブジェクトの基本的な性質です。

ご覧の通り String API は単に 任意の を変更するためのメソッドを提供していません。 String . そのため、(危険で愚かな 1 を変更することはできません。 String .

とすると、その目的は?

の主な理由は、Javaが String が不変のクラスとして設計されている主な理由は単純さです。 コアとなる文字列クラスが不変のインターフェイスを提供すれば、正しいプログラムを書くことも、他の人のコードを読んだり推論することも簡単になります。

重要な第二の理由は、文字列クラスである String がJavaセキュリティモデルに対して根本的な意味を持つということです。 しかし、これは元の言語設計...Java 1.0とそれ以前におけるドライバーであったとは思えません。

回答から行くと、同じ変数への他の参照が理由の1つであると推測されます。私の理解が正しいかどうか教えてください。

いいえ、それよりも根本的なことです。 単純に、すべての String オブジェクトは不変です。 これを理解するために、複雑な特殊ケースの推論が必要なわけではありません。 ただ、>>である<<です。

ちなみに、Javaでミュータブルな "文字列のような"オブジェクトが欲しい場合は、以下のようになります。 StringBuilder または StringBuffer . しかし、これらはStringとは異なる型です。


1 - これらのトリックが (IMO) 危険で愚かな理由は、文字列プールを介してアプリケーションの他の部分によって潜在的に共有されている文字列の値に影響を与えるからです。 これは、あなたのコードを保守する次の人が追跡するチャンスがほとんどないような方法で、...混乱を引き起こす可能性があります。