美文网首页
String内部原理

String内部原理

作者: 紫色红色黑色 | 来源:发表于2020-03-07 23:30 被阅读0次

    描述

    String内部是final修饰的char[]。下文定义方法获取String内部char[]的hashCode,验证不同的String对象内部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
    }
    

    由结果看出变量a、b、c各自的内部char[]是同一个数组。a和b是因为从常量池中取出字符串,该字符串本就是同一个对象。c是因为String构造函数中将入参的char[]赋值给对象。可以从字节码中看出。

    // #2定位到类常量池,在定位到字符串常量池中常量推送至操作数栈顶,
    0: ldc           #2                  // String abc
    // 存储变量到局部变量表下标1处
    2: astore_1
    3: ldc           #2                  // String abc
    5: astore_2
    // 堆中创建对象,对象引用推入栈顶
    6: new           #3                  // class java/lang/String
    // 复制栈顶元素
    9: dup
    // 常量池中常量推入栈顶
    10: ldc           #2                  // String abc
    // 调用构造函数初始化,参数对象引用和常量
    12: invokespecial #4                  // Method java/lang/String."<init>":(Ljava/lang/String;)V
    // 对象创建完毕存储到局部变量表下标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
    
    }
    

    由结果看出,变量a、b不是同一个对象,内部char[]也不是同一个数组。调用intern()后,a、b变成同一个对象了。

    引用

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

    相关文章

      网友评论

          本文标题:String内部原理

          本文链接:https://www.haomeiwen.com/subject/jmwkdhtx.html