知芯

java-String

2020-07-25

1. 字符串常量池

讨论版本为1.8,从1.7开始字符串常量池在堆区,之前在perm。参考美团技术团队 可能如果常量池中存在当前字符串, 就会直接返回当前字符串 一小句描述不准确,容易引起歧义。

1.1. 字符串常量池为什么在堆中:

perm区比较小,默认只有4M,频繁调用intern()方法会导致outofMemory,再者在堆区,新对象intern到常量池采用直接存储引用,不用再复制对象,性能更好。

1.2. 几个相关操作

  1. =创建字符串

    从常量池取,没有则直接存储到常量池。

  2. new String("str")创建

    "str"字符串放入常量池,然后在堆区新建一个对象,两个对象不同。

  3. String b= a.intern()

    字符串对象a如果已经存在常量池,返回的b是常量池中对应的字符串(可查看源码注释);

    1
    2
    3
    4
    5
    6
    7
    8
    9
    // 创建两个对象,一个在常量池,一个是堆区,堆区中的给a
    String a=new String("1");;
    System.out.println("a: "+System.identityHashCode(a));
    // intern时常量池已经存在,返回常量池中的给b,b!=a
    String b=a.intern();
    System.out.println("b: "+System.identityHashCode(b));
    // 从常量池取
    String c="1";
    System.out.println("c: "+System.identityHashCode(c));

    如果没有,则将a对象的引用存入常量池,然后返回的b是a的引用(因为都在堆区,1.7之前就是复制到常量池)。

    1
    2
    3
    4
    5
    6
    7
    String s3 = new String("1") + new String("1");
    System.out.println("s3: "+System.identityHashCode(s3));
    // 将堆区11对象放入常量池,1.7+直接放引用
    s3.intern();
    // 从常量池取,s4==s3。
    String s4 = "11";
    System.out.println("s4: "+System.identityHashCode(s4));
使用支付宝打赏
使用微信打赏

若你觉得我的文章对你有帮助,欢迎点击上方按钮对我打赏

扫描二维码,分享此文章