検索

ホームページ  >  に質問  >  本文

Java String的intern方法

String str1 = new StringBuilder("a").append("b").toString();
        System.out.println(str1.intern() == str1);
        String str2 = new StringBuilder("c").toString();
        System.out.println(str2.intern() == str2);

为什么输出结果是:
true
false

大家讲道理大家讲道理2890日前421

全員に返信(2)返信します

  • 高洛峰

    高洛峰2017-04-17 17:51:54

    リーリー

    Java メモリ モデルには文字列定数プールと呼ばれる領域があり、文字列定数を格納します。

    まず、jdkのバージョンが1.6以下の場合、上記のコードを実行した結果は

    となります。 リーリー

    jdk バージョンが 1.6 以降の場合、上記のコードの実行結果は

    リーリー

    上記の 2 つの異なる結果の理由は、jvm が intern() メソッドを異なる方法で実装しているためです。

    jdk1.6 以前では、intern() を呼び出します

    定数プールに等しい値を持つ文字列がない場合、jvm は文字列を作成プールにコピーし、その文字列を定数プールに返します。

    jdk1.7 以降では、intern() を呼び出します

    定数プールに等しい値を持つ文字列がない場合、jvm は現在の文字列の参照を定数プールに記録し、現在の文字列の参照を返します。

    次に、jdk1.7 以降で上記のコードが truefalse を取得する理由を説明します。

    上記のコードを含むクラスが JVM によってロードされると、定数プールがあるため、a が実行されると、リテラル定数 bcstr1.intern() が文字列定数プールにロードされます。文字列 ab が存在しない場合、JVM は定数プールに str1 の参照を記録し、str1 の参照を返します。そのため、コードの 2 行目の出力は true になります。

    str2 は、リテラル定数 c を使用して新しい文字列を構築します。この文字列の参照は、c が呼び出されるときの定数プール内のリテラル str2.intern() 文字列の参照とは異なります。プール c は既に JVM に存在しており、JVM は再構築された str2 とは異なる定数プール内の参照を直接返します。そのため、行 4 の出力は false になります。

    返事
    0
  • ringa_lee

    ringa_lee2017-04-17 17:51:54

    intern() メソッドを呼び出す String オブジェクトは、まず定数プールからオブジェクトの equals 定数を見つけて返します。見つからない場合は、オブジェクトの equals 定数を定数プールに追加します。定数の適用を返します。
    System.out.println(str1.intern() == str1); の出力は true です。これは、str1append 操作の後に定数プール内の定数への参照になるためです。
    System.out.println(str2.intern() == str2); は、str2 が変数への参照であり、定数プールにないため、false として出力されます。
    したがって、主に str.intern() == str が定数プール内の定数であるかどうかに基づいて、falsetrue であるか str であるかを判断する必要があります。そうである場合、結果は true になります。まさにfalseです。

    返事
    0
  • キャンセル返事