String內(nèi)部原理

描述

String內(nèi)部是final修飾的char[]。下文定義方法獲取String內(nèi)部char[]的hashCode,驗證不同的String對象內(nèi)部char[]是否一致

代碼

private static int showStringInternalCharArrayHashCode(String s) {
    Field value = null;
    try {
        value = String.class.getDeclaredField("value");
    } catch (NoSuchFieldException e) {
        e.printStackTrace();
    }

    if (value != null) {
        value.setAccessible(true);
        try {
            return value.get(s).hashCode();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }
    return 0;
}
public static void main(String[] args) {

    String a = "abc";
    String b = "abc";
    String c = new String("abc");

    System.out.println("a.value:" + showStringInternalCharArrayHashCode(a));
    System.out.println("b.value:" + showStringInternalCharArrayHashCode(b));
    System.out.println("c.value:" + showStringInternalCharArrayHashCode(c));
    System.out.println("a:" + System.identityHashCode(a));
    System.out.println("b:" + System.identityHashCode(b));
    System.out.println("c:" + System.identityHashCode(c));

    // a.value:1595428806
    // b.value:1595428806
    // c.value:1595428806
    // a:1072408673
    // b:1072408673
    // c:1531448569
}

由結(jié)果看出變量a、b、c各自的內(nèi)部char[]是同一個數(shù)組。a和b是因為從常量池中取出字符串,該字符串本就是同一個對象。c是因為String構(gòu)造函數(shù)中將入?yún)⒌腸har[]賦值給對象。可以從字節(jié)碼中看出。

// #2定位到類常量池,在定位到字符串常量池中常量推送至操作數(shù)棧頂,
0: ldc           #2                  // String abc
// 存儲變量到局部變量表下標(biāo)1處
2: astore_1
3: ldc           #2                  // String abc
5: astore_2
// 堆中創(chuàng)建對象,對象引用推入棧頂
6: new           #3                  // class java/lang/String
// 復(fù)制棧頂元素
9: dup
// 常量池中常量推入棧頂
10: ldc           #2                  // String abc
// 調(diào)用構(gòu)造函數(shù)初始化,參數(shù)對象引用和常量
12: invokespecial #4                  // Method java/lang/String."<init>":(Ljava/lang/String;)V
// 對象創(chuàng)建完畢存儲到局部變量表下標(biāo)3處
15: astore_3
public static void main(String[] args) {

    String a = "abc";
    String b = "aabc".substring(1);

    System.out.println("a.value:" + showStringInternalCharArrayHashCode(a));
    System.out.println("b.value:" + showStringInternalCharArrayHashCode(b));
    System.out.println("a:" + System.identityHashCode(a));
    System.out.println("b:" + System.identityHashCode(b));

    b = b.intern();

    System.out.println("a.value:" + showStringInternalCharArrayHashCode(a));
    System.out.println("b.value:" + showStringInternalCharArrayHashCode(b));
    System.out.println("a:" + System.identityHashCode(a));
    System.out.println("b:" + System.identityHashCode(b));

//        a.value:1595428806
//        b.value:1072408673
//        a:1531448569
//        b:1867083167
//        a.value:1595428806
//        b.value:1595428806
//        a:1531448569
//        b:1531448569

}

由結(jié)果看出,變量a、b不是同一個對象,內(nèi)部char[]也不是同一個數(shù)組。調(diào)用intern()后,a、b變成同一個對象了。

引用

https://dzone.com/articles/java-string-tutorials
https://dzone.com/articles/string-memory-internals

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 本文假定你對C/C++的string語法已經(jīng)有基本的了解。 如果你對C++的string的內(nèi)部實現(xiàn)原理不了解的話,...
    鐵甲萬能狗閱讀 8,234評論 0 8
  • 最全的iOS面試題及答案 iOS面試小貼士 ———————————————回答好下面的足夠了-----------...
    zweic閱讀 2,803評論 0 73
  • 在C語言中,五種基本數(shù)據(jù)類型存儲空間長度的排列順序是: A)char B)char=int<=float C)ch...
    夏天再來閱讀 4,039評論 0 2
  • 所有知識點已整理成app app下載地址 J2EE 部分: 1.Switch能否用string做參數(shù)? 在 Jav...
    侯蛋蛋_閱讀 2,710評論 1 4
  • 一. Java基礎(chǔ)部分.................................................
    wy_sure閱讀 4,012評論 0 11

友情鏈接更多精彩內(nèi)容