String,StringBuffer,stringBuilder的区别
1 string字符串对象内存情况分析

当执行第一条语句时,JVM首先通过字符串常量池查找不到内容为"abc"变量的存在,那么会 创建这个字符串对象,将刚创建的这个字符串对象放进常量池中,并且将这个引入放入str1中。
当执行第二条语句时,JVM依然通过常量池查找这个"abc"的字面量,发现在常量池中存在,于是将已经存在的这个字符串的引入返回给str2。就不会重新创建新的字符串对象了。
所以我们输出str1 == str2 是相等的,此时内存分配情况如下:

当执行第三条语句时,使用new 创建了一个字符串对象,会在堆上分配一个存放字符串对象对象的空间,然后在常量池中查找是否有该字符串,如果有则将返回引用,如果不存在则创建返回引用。所以在堆上保存的引用地址是不一样的。
参照博客:超详细,一看就懂!Java中基础对象以及String字符串对象的内存分配情况分析_江湖人称小程的博客-CSDN博客_java 字符串对象
所以我们输出str1 == str2 是不相等的,此时内存分配情况如下:

当我们平时用"+"进行字符串拼接的时候,大家说他会创建几个对象呢?

首先会在堆中创建"Hello"和"World"两个字符串对象,其次会开辟一个空间存放连接后的"HelloWorld"字符串。内存分配情况如图(图是借用的哈):

大家可能会说堆上不是只有3个对象吗?哪里来的四个呢
其实直接用"+"去拼接的时候,Java底层是调用了StringBuilder方法的。等同于
String str3 = str1 + str2; //该行会创建几个对象呢>>>>>>>>4个 等同于 str4 String str4 = new StringBuilder().append(str1).append(str2).toString();
即是一个"Hello"对象,一个"World"对象,一个StringBuilder对象,一个toString方法中新建了一个new String()对象。
由此可见String创建的字符串是不可变的,会产生大量的对象,Java中还提供了另外两个拼接字符串的类StringBuffer和StringBuilder。
2 String,StringBuffer,stringBuilder的区别
1 string为固定的长度的字符串,StringBuffer和StringBuilder为变长字符串
2 StringBuffer是线程安全的,StringBuilder是线程不安全的
3 StringBuffer和StringBuilder的默认初始值是16,可以提前预估好字符串的长度,进一步减少扩容带来的额外开销
2.1 String和StringBuffer和StringBuilder连接速度的比较
   public static void testByString(Integer count)  {
        long startTime = System.currentTimeMillis();
        String initStr = "abc";
        for (int i = 0; i < count; i++) {
            initStr = initStr + i;
        }
        long endTime = System.currentTimeMillis();
        System.out.println("String拼接字符串共消耗"+(endTime-startTime)+"ms");
    }
    public static void testByStringBuilder(Integer count)  {
        long startTime = System.currentTimeMillis();
        StringBuilder stringBuilder = new StringBuilder();
        for (int i = 0; i < count; i++) {
            stringBuilder.append(i);
        }
        long endTime = System.currentTimeMillis();
        System.out.println("StringBuilder拼接字符串共消耗"+(endTime-startTime)+"ms");
    }
    public static void testByStringBuffer(Integer count)  {
        long startTime = System.currentTimeMillis();
        StringBuffer stringBuffer = new StringBuffer();
        for (int i = 0; i < count; i++) {
            stringBuffer.append(i);
        }
        long endTime = System.currentTimeMillis();
        System.out.println("StringBuffer拼接字符串共消耗"+(endTime-startTime)+"ms");
    }
    public static void main(String[] args) {
        testByString(1000);
        testByStringBuilder(1000);
        testByStringBuffer(1000);
    }拼接1000次字符串:

拼接10000次字符串:

拼接100000次字符串:

拼接10000000次字符串(由于string拼接太多耗时太长,此次就只比较stringbuffer和stringbuilder):

由此可见,当拼接字符串的次数越多时,String的拼接效率是很低下的。stringbuffer和stringbuilder相差不大(但stringBuffer略快些)
StringBuffer类
StringBuffer类是线程安全的可变字符串序列,它是一个类似于String的字符串缓冲区,其实体容量会随着字符串增加而增加。


执行结果:

我们可以看见stringBuffer对象并没有输出出来。所以
new StringBuffer(32)是初始字符序列容量为32个字符,内存所占容量是32个字符。
 
                    
                
 
                
            
         浙公网安备 33010602011771号
浙公网安备 33010602011771号