5

文字列の作成をテストし、ハッシュコードをチェックしているときに、興味深いケースを見つけました。

最初のケースでは、コピー コンストラクターを使用して文字列を作成しました。

public class Test {

    /**
     * @param args
     */
    public static void main(String[] args) {

        String s1 = new String("myTestString");

        String s3 = s1.intern();

        System.out.println("S1: " + System.identityHashCode(s1) + "  S3:"
                + System.identityHashCode(s3));
    }


}

上記のコードの出力は次のとおりです。

S1: 816115710 S3:478684581

これは、インターンされた文字列が文字列プールから参照を選択するのに対し、s1 は新しいオブジェクトの参照を選択するため、予想される出力です。したがって、それらの ID ハッシュ コードは異なります。

char 配列を使用して文字列を作成すると、奇妙な動作が見られます。

public class Test {

    /**
     * @param args
     */
    public static void main(String[] args) {

        char[] c1 = { 'm', 'y', 'T', 'e', 's', 't', 'S', 't', 'r', 'i', 'n',
                'g' };

        String s5 = new String(c1);

        String s6 = s5.intern();

        System.out.println("S5: " + System.identityHashCode(s5) + "  S6:"
                + System.identityHashCode(s6));
    }

}

上記のコードの出力は次のとおりです。

S5: 816115710 S6:816115710

これは予期しない出力です。インターンされた文字列と新しい文字列オブジェクトが同じアイデンティティハッシュコードを持つにはどうすればよいですか??

何か案は?

4

1 に答える 1

3

最初のケースでは、myTestStringリテラルはを呼び出すinternにプールにありますが、2 番目のケースではそうではなく、文字列s5が直接プールに入れられます。

例を段階的に見ていくと、次のようになります。

  • String s1 = new String("myTestString");=> String リテラルを使用するとmyTestString、プールに String が作成され (これを と呼びましょうs0)、プールにない新しい Strings1も作成されます。
  • String s3 = s1.intern();=> プールに同等の String があるかどうかをチェックし、 を見つけs0ます。ここで、同じインスタンスs3s0参照します (つまりs3 == s0、真ですがs1 != s0)。

あなたの2番目の例では:

  • String s5 = new String(c1);プールにない新しい文字列を作成します
  • String s6 = s5.intern();がプール内にあるかどうかをチェックmyTestStringしますが、それを見つけることができないため、 への呼び出しは と同じ String を参照internする新しい String参照s5をプールに作成します。そうs6 == s5です。

最後に、これら 2 つのプログラムを実行して、私の説明を確認できます (2 番目のプログラムはtrue3 回出力されます)。

public static void main(String[] args) {
    String s1 = new String("myTestString");
    String s3 = s1.intern();
    System.out.println("myTestString" == s1);
    System.out.println(s3 == s1);
    System.out.println("myTestString" == s3);
}

public static void main(String[] args) {
    String s1 = new String(new char[] {'m', 'y', 'T', 'e', 's', 't', 'S', 't', 'r', 'i', 'n', 'g'});
    String s3 = s1.intern();
    System.out.println("myTestString" == s3);
    System.out.println("myTestString" == s1);
    System.out.println(s3 == s1);
}
于 2013-05-19T09:33:22.917 に答える