String详解

1.String的基本特性

  String的String Pool是一个固定大小的Hashtable,默认值大小是长度是1009.如果放进String Pool的String 非常多,就会造成Hash冲突严重,从而导致链表会很长,而链表很长的直接影响是调用String.intern时性能会大幅下降;

  使用-XX:StringTableSize可以设置StringTable的长度

  在JDK6中StringTable时固定的,就是1009的长度,所以常量池的字符串过多,就会导致效率下降很快,StringTableSize设置没有要求;

  在JDK7中,StringTable的长度默认值是60013,StringTableSize设置没有要求;

  在JDK8中,设置StringTable的长度,1009是可设置的最小值;

 

2.使用String类型常量池的方式

  1.使用双引号方式声明对象:String str =“String”;

  2.使用String类提供的intern()方法

 

3.不同JDK版本String常量池的存放位置

  1.JDK6及以前,String常量池存放在永久代上;

  2.JDK7后,字符串常量池调整存放在Java堆内;

    所有的字符串都保存在堆中,和其他普通对象一样,在进行调优应用时仅需要调整堆的大小就可以了;

4.字符串拼接操作

  1.常量与常量的拼接结果放在常量池当中, 原理是编译器优化

  2.常量池不会存在相同内容的常量

  3.只要其中有一个时变量,结果就在堆中相当于new了一个对象。变量拼接的原理是StringBuilder

  4.如果拼接的结果调用intern()方法,则主动将常量池中还没有的字符串对象放入池中,并返回此对象 地址

public void test(){
        String s1 = "javaEE";
        String s2 = "hadoop";

        String s3 = "javaEEhadoop";
        String s4 = "javaEE" + "hadoop";//编译期优化
        //如果拼接符号的前后出现了变量,则相当于在堆空间中new String(),具体的内容为拼接的结果:javaEEhadoop
        String s5 = s1 + "hadoop";
        String s6 = "javaEE" + s2;
        String s7 = s1 + s2;

        System.out.println(s3 == s4);//true
        System.out.println(s3 == s5);//false
        System.out.println(s3 == s6);//false
        System.out.println(s3 == s7);//false
        System.out.println(s5 == s6);//false
        System.out.println(s5 == s7);//false
        System.out.println(s6 == s7);//false
        //intern():判断字符串常量池中是否存在javaEEhadoop值,如果存在,则返回常量池中javaEEhadoop的地址;
        //如果字符串常量池中不存在javaEEhadoop,则在常量池中加载一份javaEEhadoop,并返回次对象的地址。
        String s8 = s6.intern();
        System.out.println(s3 == s8);//true
    }

  5.字符串拼接的底层实现不一定使用StringBuilder,当符号拼接左右两边为字符串常量或常量引用,会在编译期优化

public void test1(){
        final String s1 = "a";
        final String s2 = "b";
        String s3 = "ab";
        String s4 = s1 + s2;
        System.out.println(s3 == s4);//true
    }

  6.StringBuilder使用优化:在基本确定字符串长度时,尽量初始化一个对应大小的初始容量值,避免扩容造成性能消耗

posted @ 2020-09-13 18:32  宇枫  阅读(811)  评论(0编辑  收藏  举报