Java仮想マシンは、文字列オブジェクトを格納するための独立したメモリ領域内で開いて、このメモリ領域は、文字列プールと呼ばれています。どのようにJavaの文字列バッファプールは仕事ですか?
次のコード例:
String a = "abc";
String b = "abc";
String c = new String("xyz");
列A =「ABC」、プール内の最初の検索文字列が全く同じオブジェクトを持たない場合、同じオブジェクトが返された場合、直接文字列バッファプール内のオブジェクト、そうでない場合は同じオブジェクトを参照し、文字列を作成オブジェクトとアプリケーションの戻りオブジェクトを作成します。このステップのために、プールが「ABC」の文字列オブジェクトではなく、最初の文字列オブジェクトを作成し、オブジェクトとの参照を返します。
列B =「ABC」;これはまた、点b「ABC」このオブジェクトへのオブジェクト参照変数を作成したいです。このとき、第1の検索文字列バッファプールは、オブジェクトを直接ただし、このとき、aとbは、オブジェクト「ABC」を共有するバックBに参照することができ、「ABC」が対象であったが見つかりました。文字列が一定であるため、作成した後、あなたは新しいオブジェクトを作成しない限り、修正方法はありません、Bに影響を受けた文字列の変更を心配しないでください。
列c =新しい文字列(「XYZ」);文字列=新しい文字列(「ABC」)のJavaソースコードを以下のように本工法を達成するためには、次のとおり公共ストリング(文字列元){this.value = original.valueと、この.hash = original.hash;}。文字列バッファ・プールを見つけ、その参照を返すそのようにプール内の文字列「XYZ」オブジェクトを作成し、この文字列オブジェクトなし「XYZ」を見つけていない、と。
新しい文字列は、必ずしも新しいオブジェクトを作成していない場合、それは、分析の上部から分かるように、同じオブジェクトの他の参照変数とが一緒に使用されてもよいです。ここで参照するには、文字列バッファプールに関するいくつかの一般的な質問があります。
最後に次の文は、いくつかのStringオブジェクトを作成するには?
String a = "abc";
String b = "abc";
String c = new String("xyz");
String d = new String("xyz");
String e = "ab" + "cd";
このプログラムは、我々は比較を見て、上記のプログラムと非常によく似ています:
列A =「ABC」、この文のプールが「ABC」の文字列オブジェクトではありませんので、それはオブジェクトを作成するには、列B =「ABC」、私はしませんので、彼らは、プール内の「ABC」対象となっているので、あなたは、新しいオブジェクトを作成します。文字列cは=新しい文字列(「 XYZ」); この文字列オブジェクトの「XYZ」の不在は、それが最初のオブジェクトの「XYZ」を作成し、そのオブジェクトは、文字列コンストラクタとして文字列であります(プールしない)ので、メモリ内に二つのオブジェクトの合計を作成する、新しい文字列オブジェクトを作成し;省略するは、オブジェクト処理,;列D =新しい文字列(作成作成 「XYZ」)をオブジェクト、文字列E =「AB」+ 「CD」、 コンパイル時定数の値を決定したからです。この文は、文字列E =「ABCD」と同等ですので、オブジェクトを作成します。
だから、作成されたオブジェクトの数は以下の通りです1,0,2,1,1。
最終的にはそれと等しくないかと等しく決定?
私たちは、など、、==等しいが、文字列バッファ・プールを学んだ後、あなたは==使用しない理由を知っておくべき2つの文字列オブジェクトの同じJavaを学習することは、使用を決定するために使用することができないことを知っている==、と事情は同じであるか下価格、まず、あなたが知っている必要がありますが、比較は== 2つのオブジェクトが等しいメモリアドレスであるということです、ここではいくつかのプログラムに目を通します。
public static void main(String[] args) {
String s1 = "Monday";
String s2 = "Monday";
if (s1 == s2)
System.out.println("s1 == s2");
else
System.out.println("s1 != s2");
}
出力:S1 == S2
分析:文字列バッファのプールの上記した説明では、我々はすなわち、メモリアドレスが同じになるようにS1およびS2は、プール内の同じオブジェクトの文字列へのポインタであることを知って、2つの文字列が等しいかどうかを判断することができる==と。
public static void main(String[] args) {
String s1 = "Monday";
String s2 = new String("Monday");
if (s1 == s2)
System.out.println("s1 == s2");
else
System.out.println("s1 != s2");
if (s1.equals(s2))
System.out.println("s1 equals s2");
else
System.out.println("s1 not equals s2");
}
出力:S1 = S2; s1がs2の等しいです!
分析:私たちを知っているの上に分析、文字列s2を=新しい文字列(「月曜日」);これらの言葉は、文字列バッファプールに新しいオブジェクトを作成しますが、メモリ内の別の場所に新しいオブジェクトを作成しますので、S1はありません文字列バッファ・プールへのポインタであり、S2は、他の、二つの異なるメモリアドレスのメモリ位置を指しています。
public static void main(String[] args) {
String s1 = "Monday";
String s2 = new String("Monday");
s2 = s2.intern();
if (s1 == s2)
System.out.println("s1 == s2");
else
System.out.println("s1 != s2");
if (s1.equals(s2))
System.out.println("s1 equals s2");
else
System.out.println("s1 not equals s2");
}
出力:S1 == S2; s1がs2のと等しいです
分析はまず、このバーの役割のインターン()メソッドは、このメソッドの役割は、オブジェクト参照ストリング・バッファ・プールを返すことであることを、アドレスがS2の文字列バッファプールによって指され、S1されるに等しいです。 。
public static void main(String[] args) {
String Monday = "Monday";
String Mon = "Mon";
String day = "day";
System.out.println(Monday == "Mon" + "day");
System.out.println(Monday == "Mon" + day);
}
出力:真、偽
分析:なぜ我々が言ってきたように、両方が定数であるので、コンパイル段階で決定することができたので、最初のものであるが、trueに等しいです。第1に、彼の値を予め決定することができないので、その日は、可変であるので、両者は等しくありません。この例から、我々は、接続の両側にのみ+時刻文字列定数で見ることができ、参照は、文字列バッファ・プールを指すか、またはメモリ内の別のアドレスを指しています。
public static void main(String[] args) {
String Monday = "Monday";
String Mon = "Mon";
final String day = "day";
System.out.println(Monday == "Mon" + "day");
System.out.println(Monday == "Mon" + day);
}
出力:真、真
分析:あなたは、コンパイル時にその正確な値を知ることができた場合、コンパイラは、最終的な変数の代わりに使用され、使用するコンパイル時定数として、それは、この定数の同等に直接アクセスし、実行する必要はありません。 OK。したがって、第2の文は、文字列バッファ・プールへの参照点です。
public static void main(String[] args) {
String Monday = "Monday";
String Mon = "Mon";
final String day;
day = "day";
System.out.println(Monday == "Mon" + "day");
System.out.println(Monday == "Mon" + day);
}
出力:真、偽の
分析は:のみコンパイル時に変数の最終値の正確事例を知ることができ、コンパイラは上記のコードが最適化されることはありません、この最適化を実行します。