-
s = new String("xyz"); いくつの String オブジェクトが作成されますか? 1 つは "xyx"、もう 1 つは "xyx" を指す参照オブジェクトです。
String s="Hello";int s=i+s; Java では、データ型が一致しないというメッセージが表示されます。 string はクラスであるため、正しいアプローチ: s+="3" または s+='3' または s+=(char)i;
String オブジェクト (引用符で囲まれたテキスト) を作成する別の方法を紹介します。このメソッドは String に固有であり、新しいメソッドとは大きく異なります。
JAVA 仮想マシン (JVM) には文字列プールがあり、多くの文字列オブジェクトを保存し、共有できるため、効率が向上します。 String a="abc"; の場合、このコード行が実行されると、JAVA 仮想マシンはまず文字列プールを検索して、値「abc」を持つそのようなオブジェクトが既に存在するかどうかを確認します。判断基準は String classquals(Object. obj) メソッドの戻り値。存在する場合、新しいオブジェクトは作成されず、既存のオブジェクトへの参照が直接返されます。存在しない場合は、最初にオブジェクトが作成され、次に文字列プールに追加されてから、その参照が返されます。
文字列オブジェクトの作成: Java では、文字列オブジェクト [一般的にオブジェクトです] が広範囲に使用されるため、メモリ領域と実行時間を節約するために [文字列を比較するときなど、オブジェクトは常にヒープ内にメモリを割り当てます]。 == は、equals() よりも優れており、すべての文字列リテラルはコンパイル段階でリテラル プールに入れられ、ランタイム リテラル プールは定数プールの一部になります。リテラル プールの利点は、プール内のすべての同じ文字列定数がマージされ、1 つのスペースのみを占有することです。 2 つの参照変数について、== を使用して、それらの値 [references] が等しいかどうか、つまり、同じオブジェクトを指しているかどうかを判断することがわかります。
ここで、String s = new String("abc"); ステートメントを見てください。ここで、「abc」自体はプール内のオブジェクトであり、実行時に new String() が実行されると、そのオブジェクトのコピーがプール内に配置されます。ヒープ内にあり、ヒープ内のこのオブジェクトの参照を s に渡します。 OK、このステートメントは 2 つの String オブジェクトを作成します。
String s1 = new String("abc") ;String s2 = new String("abc") ;if( s1 == s2 ){ //実行されないステートメント}
//文字列オブジェクトはいくつ作成されましたか? [3 つ、プールに 1 つ、ヒープに 2 つ。 】
テキストを含めるために引用符を使用して作成された String オブジェクト間の「+」接続によって生成された新しいオブジェクトのみが文字列プールに追加されます。新しいメソッドで作成された新しいオブジェクト (null を含む) を含むすべての「+」接続式では、生成された新しいオブジェクトは文字列プールに追加されません。
1.== は同じオブジェクトから参照されていることを意味し、equals() は値が等しいことを意味します。
String str1 = "abc"; 参照されるオブジェクトはスタック (または String プール) 上にあります。
String str1 =new String ("abc"); 参照されたオブジェクトはメモリ/ヒープ内にあります。
2.スタック内の文字列 str1 = "文字列";
スタック上の文字列 str3 = "str";
スタック上の文字列 str4 = "ing";
ヒープ内の String str2 = str3+str4; これは、+ 記号の機能が、スタック上の文字列値を検索するのではなく、新しく作成された別の String オブジェクトを返すことであるためです。 String str2 = "str"+"ing"; の場合、最終結果はスタック上にあります。 str1==str2 は true です。
しかし、注意を要する状況が 1 つあります。以下のコードを見てください。
パブリック クラス StringStaticTest {
public static Final String A = "ab" // 定数 A;
public static Final String B = "cd" // 定数 B;
public static void main(String[] args) {
String s = A + B // 2 つの定数を + で接続して s を初期化します。
文字列 t = "abcd";
if (s == t) {
System.out.println("s は t に等しい、それらは同じオブジェクトです");
} それ以外 {
System.out.println("s は t と等しくありません。同じオブジェクトではありません");
}
}
}
このコードを実行した結果は次のようになります。
s は t に等しい、それらは同じオブジェクトです
理由は、上記の例では、AとBが定数でその値が固定されているため、sの値も固定であり、クラスのコンパイル時に決定されているためです。つまり、 String s=A+B; は String s="ab"+"cd"; と同等です。
上記の例を少し変更して、何が起こるか見てみましょう。
パブリック クラス StringStaticTest {
public static Final String A;
public static Final String B;
静的 {
A = "ab";
B = "cd";
}
public static void main(String[] args) {
// 2 つの定数を + で接続して s を初期化します。
文字列 s = A + B;
文字列 t = "abcd";
if (s == t) {
System.out.println("s は t に等しい、それらは同じオブジェクトです");
} それ以外 {
System.out.println("s は t と等しくありません。同じオブジェクトではありません");
}
}
}
その操作の結果は次のようになります。
s は t と等しくありません。それらは同じオブジェクトではありません
少し変更を加えただけで、結果は先ほどの例とはまったく逆になります。もう一度分析してみましょう。 A と B は定数として定義されていますが (1 回のみ割り当て可能)、すぐには割り当てられません。 s の値が計算される前、それらがいつ割り当てられるか、どのような値が割り当てられるかはすべて変数です。したがって、A と B は、値が割り当てられる前は変数のように動作します。この場合、 はコンパイル時に決定できず、実行時にのみ作成できます。
最後に、JAVA 仮想マシン (JVM) 内の String オブジェクトのストレージと、文字列プールとヒープおよびスタックの関係について説明します。まず、ヒープとスタックの違いを確認してみましょう。
スタック: 主に基本型 (または組み込み型) (char、byte、short、int、long、float、double、boolean) とオブジェクト参照を保存します。データは共有でき、その速度は登録に次ぐものです。ヒープ。
ヒープ: オブジェクトを保存するために使用されます。
String クラスのソース コードを見ると、String オブジェクトの値を格納する value 属性があることがわかります。これは、文字列が文字のシーケンスであることも示しています。 String a="abc"; を実行すると、JAVA 仮想マシンはスタックに 3 つの char 値「a」、「b」、「c」を作成し、ヒープに String オブジェクト、その値 (value ) を作成します。スタック上に作成された 3 つの char 値の配列 {'a', 'b', 'c'} 最後に、新しく作成された String オブジェクトが文字列プールに追加されます。
次に String b=new String("abc"); コードを実行すると、「abc」が作成されて文字列プールに保存されているため、JAVA 仮想マシンはヒープ内に新しい String オブジェクトを作成するだけですが、 value は、コードの前の行が実行されたときにスタック上に作成された 3 つの char 型の値 'a'、'b'、および 'c' です。
この時点で、この記事の冒頭で取り上げた String str=new String("abc") がなぜ 2 つのオブジェクトを作成するのかという疑問はすでにかなり明確になっています。
この記事は CSDN ブログからのものです。転載する場合は出典を明記してください: http://blog.csdn.net/akihappy/archive/2009/03/10/3977169.aspx
この記事は CSDN ブログからのものです。転載する場合は出典を明記してください: http://blog.csdn.net/Foxalien/archive/2009/12/18/5029470.aspx
-