String、StringBuild、StringBuffer

  • Post author:
  • Post category:其他




String、StringBuild、StringBuffer

String、StringBuild、StringBuffer在java中都是可以操作字符串的对象,让我们来看看它们之间的区别和联系。



从结构分析

从结构上来看,它们都是final类,并且都是用char数组来存储内容的,不过StringBuild、StringBuffer没有用final和private来修饰这个数组。

StringBuild、StringBuffer都是继承AbstractStringBuilder,但StringBuffer为了解决线程安全问题,在对应的方法加上了关键字。



从线程是否安全分析

从线程安全方面来讲,String是不可变的,所以是线程安全的,因为多个线程调用String的方法都会去产生一个新的String,不会改变最初的内容。(之前我总是认为String做拼接的时候,是线程不安全的,所以String是线程不安全的,其实他指的线程安全并不是这个意思,因为拼接已经不是原子操作了,它只是指Sring调String的方法不会发生线程安全问题。)

StringBuild是非线程安全的,StringBuild也是用char数组去存储的,它其中某些方法是直接去操作这个数组的,比如append方法所以在多线程情况下是不安全的。

StringBuffer是线程安全的,虽然StringBuffer和StringBuild方法和属性几乎一样、都是继承AbstractStringBuilder。但是StringBuffer的方法有synchronize修饰。



String和StringBuild

String对象用“+”去拼接时,其实是使用了StringBuild对象。`

 public static void main(String[] args)  {
       String a="mihou";
       String b="tao";
       String c=a+b;
    }

在这里插入图片描述
上面是测试代码和对应的字节码。我们可以看到字节码中,先初始化了两个String对象,然后再新建了一个StringBuild对象,再调用了StringBuild的append方法,将两个String对象拼接进去,然后返回StringBuild的toString。

public String toString() {
        // Create a copy, don't share the array
        return new String(value, 0, count);
    }

StringBuild的toString是返回一个String对象。

String c=“mihou”+“tao”,这个语句是没有创建StringBuild对象的,因为前面我们讲了必须是一个String对象使用了“+”,而“mihou”+“tao”其实只在常量池里面创建了“mihoutao”这一个对象,如果说“mihou”或者“tao”是String对象的话,就会创建StringBuild。那怎么去验证没有创建“mihou”对象呢?这里有两种办法,一种是去看字节码。

在这里插入图片描述

这里我们可以看到只初始化了一个“mihoutao”。

还有一种办法是使用intern方法,jdk至少1.7。

public static void main(String[] args) {
       String a="mihou"+"tao";
       String b=new String("mi")+new String("hou");
       System.out.println(b.intern()==b);
    }

这里输出是true,刚好证明了常量池中没有”mihou”对象。



从效率分析

上面我们讲了String在拼接时底层使用了Stringbuild,所以在这种拼接的时候效率是一样的,不过在循环中拼接就会循环创建Stringbuild,这时效率就会低些。而用Stringbuild可以把对象创建在循环外,避免这种情况。

String中的方法,每次对产生新的对象,而Stringbuild是在原来的基础上修改,所以String的开销大些。

Stringbuild和StringBuffer的差别在于StringBuffer要加锁,释放锁。主要的开销大小区别就在这里,所以Stringbuild的效率高。

综上所述,Stringbuild的效率总体来说是高于String和StringBuffer。String和StringBuffer的效率就要具体分析了,主要是看锁消耗和频繁创建对象哪个开销大。



版权声明:本文为bangemihoutao原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。