jdk分析のString

8840 ワード

public class StringDemo01 {

    public static void main(String[] args) {

        String s1 = new String("abc"); // a 

        String s2 = "abc"; // b 

        String s3 = new String("abc"); // c



        System.out.println(s1 == s2); //false

        System.out.println(s1 == s3); //false

        System.out.println(s2 == s3); //false



        System.out.println(s1 == s1.intern()); //false

        System.out.println(s2 == s2.intern()); //true 

        System.out.println(s1.intern() == s2.intern()); //true



        String lo = "lo";

        String hel = "hel";

        System.out.println("hello" == "hel" + "lo"); // d //true

        System.out.println("hello" == "hel" + lo); // e //false

        System.out.println("hello" == hel + "lo"); // f //false

    }

}

1、いくつかのオブジェクトを生成する


質問:プログラムのa、b、c行目を実行した後、それぞれいくつかのオブジェクトが生成されます.それぞれは何ですか.理由は?
1)aを実行した後、2つのオブジェクトを生成する.
まずString Poolで「abc」という文字列があるかどうかを探します.ないとString Poolで「abc」オブジェクト1に生まれ変わり、new String(「abc」)操作でJavaメモリのスタックに「abc」Stringクラスオブジェクト2が生成されます.
変数s 1は、スタックに格納され、スタック内の「abc」Stringオブジェクトを指す参照である.
2)bの実行後、0個のオブジェクトを生成する.
String s2= "abc"; この文プログラムは、String s 1=new String(「abc」)であるため、実行中にString Poolに「abc」という文字列オブジェクトを探します.の場合すでにString Poolで「abc」オブジェクトが生成されているため、実行済み
この文の後もスタックに存在するs 2オブジェクトは、String Poolに格納された「abc」Stringオブジェクト、すなわち、s 2に格納された「abc」Stringオブジェクトのアドレスを指す.
3)cを実行した後、1つのオブジェクトを生成する.
同様に、まずString Poolで「abc」Stringオブジェクトがあるかどうかを検索し、すでに存在していることを発見し、newによって新しい「abc」Stringオブジェクトを生成し、そのアドレスを参照変数s 3に割り当てる.
 
この例では、3つの参照変数s 1,s 2,s 3がそれぞれ3つの異なるオブジェクトを指し、3つの異なるメモリアドレスが格納されているため、3つのうちの任意のものを「==」で比較するのはfalseである.
s 1-------String Poolのオブジェクトのコピーであるスタック内のオブジェクト.
s 2-------String Pool定数プールの「abc」Stringオブジェクト;
s 3-------String Poolのオブジェクトのコピーであるスタック内のオブジェクト.
==判断小結:
1)生データ型に対して"=="はデータの数値を比較する.2)参照データ型の場合,===は常にオブジェクトのメモリアドレスである.
 
2、intern
JDKドキュメントを見ると、2つのStringタイプsとtがある場合、s.equals(t)のみの場合、s.intern()=t.intern()、すなわち、sとtの内容が等しい場合、s.intern()とt.intern()は、String Pool内の同じオブジェクトに戻る参照であることがわかります.
同じオブジェクトの参照先である以上、必ず同じです.s.intern()を解析すると、まずString Pool定数プールに「abc」文字列があるかどうかを検索し、s.intern()の戻り値が定数プールの「abc」のアドレスであり、ない場合はstring poolに追加し、アドレスを返します.
したがって、s.intern()=s 1という関係が得られる.intern()=s2.intern()=s1
s 1はスタックを指すが、s 1.intern()は定数プールを指す.
s 2は定数プールを指す、s 2.intern()は定数プールを指す.
s1. intern()は定数プール、s 2を指す.intern()は定数プールを指す.
 
3、文字列のつづり
d行目「+」の両端は2文字の値である定数であるため、1つの「hello」に接続され、String Pool定数プールで見つけることができ、新しいオブジェクトは生成されず、等号両端のアドレスはString Poolの「hello」のアドレスであるため、等しく、trueに戻る.
第eについて、f行"+"の両端の1つは字面値である定数であり、もう1つは変数であり、つなぎ合わせることができないため、スタックの中で1つの"abc"のオブジェクトが生成され、スタックの中の1つのオブジェクトとString Pool定数プールの中の1つのオブジェクトはもちろん2つのオブジェクトであり、アドレス値は間違いなく一致しない
などということでfalseに戻ります.
定数プール:JVM内の独立した領域に文字列定数と基本型定数を格納する(public static final)
 
4、Javaの文字列は漢字を表すことができますか?
Javaでは1文字が16ビットを表し、2バイト(1 byte=8 bit)に相当し、1文字が2バイトを占有する.
 
5、String s = "Hello"; s = s + "world!";この2行のコードを実行すると、元のStringオブジェクトの内容はいったい変わりましたか?
Stringオブジェクトの内容は変更できません.最後にhelloworldを指しましたが、元のStringオブジェクトの内容はhelloで変更されていません.ただ、今はそれを指していません.
 
6、String s = new String("xyz");String Objectはいくつ作成されましたか?両者の間にはどんな違いがありますか.
2つのオブジェクトが作成され、string poolの1つがスタックに作成されます.
 
7、StringとStringBufferの違い
Stringはfinalタイプで、内容は変更できません.StringBufferの内容は変更できます.
StringはequalsメソッドとhashCodeメソッドを書き換えたが,StringBufferは持たなかった.
 
8、StringBufferとStringBuilderの違い
StringBufferはスレッドが安全です.
StringBuilderは非スレッドセキュリティの性能が高い点で、StringBuilder、JDK 5以降に現れることをお勧めします.
 
9、次の文は全部で何個のオブジェクトを作成しましたか.String s=「a」+「b」+「c」+「d」
一つ.JVMはコンパイル時に最適化され、「abcd」の文字列を直接定義することに相当する.
String s = "a"+"b"+"c";いくつのオブジェクトが生成されますか?
オブジェクトが生成されるだけで、コンパイル期間は定数プールに格納されることを決定します.
変数を含む文字列コネクタ、例えば「aa」+s 1を使用して作成されたオブジェクトは、実行期間によって作成され、スタックに格納されます.
 
10、String練習
String str1 = "a";

String str2 = "b";

String str3 = "ab";

String str4 = str1 + str2;

String str5 = new String("ab");



System.out.println(str5.equals(str3));  //true

System.out.println(str5 == str3); //false

System.out.println(str5.intern() == str3); //true

System.out.println(str5.intern() == str4); //false





String a = new String("ab");

String b = new String("ab");

String c = "ab";

String d = "a" + "b";

String e = "b";

String f = "a" + e;



System.out.println(b.intern() == a); //false

System.out.println(b.intern() == c); //true

System.out.println(b.intern() == d); //true

System.out.println(b.intern() == f); //false

System.out.println(b.intern() == a.intern()); //true





String a = "abc";

String b = "abc";

String c = "a" + "b" + "c";

String d = "a" + "bc";

String e = "ab" + "c";



System.out.println(a == b); //true

System.out.println(a == c); //true

System.out.println(a == d); //true

System.out.println(a == e); //true

System.out.println(c == d); //true

System.out.println(c == e); //true