Java の String クラスは非常に一般的に使用されるクラスですが、その詳細にはほとんど注意が払われていないため、ほとんどのインタビューはこのクラスに焦点を当てます。たとえば、 String str = new String("hello"); は、いくつかのメモリ空間、String と StringBuffer の違いなどを開きます。私の理解は次のとおりです:
String は Final によって変更されたクラスであり、継承することはできません。 StringBuffer も、final によって変更されたクラスです。
1. JVM のメモリ分割
Java には主に 4 つのメモリ空間があります: スタック メモリ空間、ヒープ メモリ空間、グローバル データ領域、グローバル コード領域
1. スタック メモリ空間: すべてのオブジェクトを保存します。 name (参照されたヒープメモリ空間のアドレスを保持)
2. ヒープメモリ空間: 各オブジェクトの特定の内容を保存します
3. グローバルデータ領域: 静的型のデータ属性(グローバルデータ)を保存します
4. グローバルコード領域: すべてのメソッド定義を保存します
JVM では、ヒープメモリはオブジェクトのインスタンス化の内容 (プログラムデータ) を格納するメモリ空間であり、スタックメモリはオブジェクトの名前を格納します。対応するヒープを指すアドレス。
また、次のようにも言えます。すべてのオブジェクト名はスタック メモリに格納され、オブジェクトの特定の内容はヒープ メモリに保持されます。参照型データは、ヒープ メモリの領域を空けるために new キーワードを使用する必要があります。
2. Sring のメモリ割り当て
String には特別な機能があります。String オブジェクトを構築するときに、new 構築または "hello" 直接構築を使用できます。 2 つの方法のうち、2 番目の方法を使用することをお勧めします。
1. String a = "hello";
2. String a= new String("hello");
説明は次のとおりです:
1: a のオブジェクト参照がスタックに定義されていますヒープを指すメモリ。メモリの値は「hello」メモリ アドレスです。ついに記憶空間がオープンしました
2: a のオブジェクト参照がスタック メモリ内で再定義され、最初にヒープ メモリ内の "hello" のメモリ アドレスを指し、次に新しい後にヒープ メモリ内の "hello" のアドレスを指します。最終的に、2 つのスペースが開かれました。最初のスペースにはオブジェクト参照がなく、JVM によってガベージ コレクションが行われます。
図は次のとおりです:
次のコードを理解するのは難しくありません:
package andy.string.test; /** * @author Zhang,Tianyou * version:2014-11-25 下午4:15:14 * * */ public class TestString { public static void main(String[] args){ String a = "hello"; String b = "hello"; String c = new String("hello"); String d = new String(); d = "hello"; String e = c; System.out.println("a==b ? " + (a== b)); System.out.println("a==c ? " + (c== b)); System.out.println("a==d ? " + (a== d)); System.out.println("a==e ? " + (a== e)); System.out.println("c==d ? " + (c== d)); System.out.println("c==e ? " + (c== e)); } }
a==b==d だけがあります。 c=e。
説明:
1. string は、new されるたびにヒープメモリを待ちたくないので、new が新しいアドレスを割り当てた後、d は new の後のアドレスを放棄し、メモリアドレスを指します。 a に対応するため、それらは同一です。
2. "hello" 代入の直接代入方法が指すヒープメモリ空間は同じです。 String は Java の共有デザインを使用します。このオブジェクト プールは、複数のオブジェクトを保存できます。新しくインスタンス化されたオブジェクトがオブジェクト プールにすでに存在する場合、そのオブジェクトは繰り返し定義されず、オブジェクト プールから直接使用されます。 。したがって、既存のコンテンツの場合、オブジェクトはすでにインスタンス化されているオブジェクトのスペース アドレスを指します。
3. String、StringBuffer、StringBuilderの違い
違いは、StringBuilder はスレッド同期されていないため、その操作は StringBuffer よりも効率的である必要があることです。
実際、上記のコードはメモリ内に 3 つのスペース、つまり「hello」、「andy」、「helloandy」を解放し、それらのヒープ メモリ サイズは固定されており、最後に str は「helloandy」のヒープ アドレスを指します。 。以下の図に示すように、 StringBuffer を使用すると、メモリ空間は 1 つだけ開かれ、APEND を使用して削除などの操作内容を追加できます。
したがって、文字列に値を循環的に代入する場合は、メモリを節約してパフォーマンスを向上させることができる StringBuffer (スレッドセーフ) または StringBuilder を使用するのが最善です。 上記は、Java の String、StringBuffer、StringBuilder の違いとスタック メモリの割り当てを図で紹介したものです。さらに関連する内容については、PHP の中国語 Web サイト (www.php.cn) に注目してください。