搜尋

首頁  >  問答  >  主體

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

大家讲道理大家讲道理2894 天前437

全部回覆(2)我來回復

  • 高洛峰

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

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

    java 記憶體模型中存在一個叫做 String常數池的區域,其中存放著字串常數。

    先說明一下,在jdk版本小於等於1.6的時候,執行上述程式碼的結果會是

    false
    false

    jdk 版本大於1.6 時,上述程式碼的執行結果為

    true
    false

    造成以上兩種不同結果的原因是,jvm對 intern()方法的實作不同。

    在jdk1.6及以前,調用intern()

    如果常數池中不存在值相等的字串時,jvm會複製一個字串到創量池中,並傳回常數池中的字串。

    而在jdk1.7及以後,調用intern()

    如果常數池中不存在值相等的字串時,jvm只是在常數池記錄當前字串的引用,並傳回目前字串的引用。

    接下來,我們再解釋上述代碼在jdk1.7及以上jdk中為什麼會得到一個true一個falsetrue一个false

    当存在上述代码的类被JVM加载时,字面值常量 a, b, c 就会被加载到 string 常量池中,当执行str1.intern()时,由于常量池中并不存在字符串ab,jvm 会在常量池中记录str1的引用,并返回str1的引用,因此,第2行代码的输出为true

    str2使用字面值常量 c 构造了一个新的字符串,该字符串的引用和常量池中字面值c字符串的引用不相同,当调用str2.intern()时, 常量池中已经存在了c,jvm直接返回常量池中的引用,该引用不同于重新构造的str2,因此第4行代码的输出为false

    當存在上述程式碼的類別被JVM載入時,字面值常數a, b, c 就會被載入到string在常數池中,執行str1.intern()時,由於常數池中並不存在字串ab,jvm 會在常數池中記錄str1< /code>的引用,並傳回str1的引用,因此,第2行程式碼的輸出為true。 #🎜🎜# #🎜🎜#str2使用字面值常數c 建構了一個新的字串,該字串的引用和常數池中字面值c字串的引用不相同,當呼叫str2.intern()時, 常數池中已經存在了c,jvm直接傳回常數池中的引用,該引用不同於重新建構的str2,因此第4行程式碼的輸出為false。 #🎜🎜#

    回覆
    0
  • ringa_lee

    ringa_lee2017-04-17 17:51:54

    一個String物件呼叫intern()方法会先从常量池中找到equals该对象的常量并返回,若找不到就在常量池中增加一个equals该对象的常量,并返回该常量的应用。
    System.out.println(str1.intern() == str1);输出为true,是因为str1经过append操作后,变成一个常量池中常量的引用。
    System.out.println(str2.intern() == str2);输出为false,是因为str2是一个变量的引用,不在常量池中。
    因此,我们要判断str.intern() == strfalse还是true,主要看str是不是常量池中的常量,如果是结果就是true,否则就过就是false

    回覆
    0
  • 取消回覆