String,StringBuffer,StringBuilder的区别

1.String和StringBuffer的区别

       (1)String用于字符串操作,属于不可变类,而StringBuffer也是用于字符串操作,不同之处是StringBuffer属于可变类。String是不可变类,也就是说,String对象一旦被创建,其值不能改变,而StringBuffer是可变类,当对象被创建后仍然可对其值进行修改。由于String是不可变类,因此适合在需要被共享的场合使用,而当一个字符串经常需要被修改时,在字符串被修改时会比StringBuffer多很多附加的操作,同时会产生很多无用的对象,由于这些无用的对象会被垃圾回收器来回收,因此会影响程序的性能。在规模小的项目里面这个影响很小,但是在一个规模大的项目里面,这会对程序的运行效率带来很大的影响。

        (2)String与StringBuffer的另外一个区别在于当实例化String时,可以利用构造函数(String s1 = new String("world"))的方式来对其进行初始化,也可用赋值(String s="Hello")的方式来初始化,而StringBuffer只能使用构造函数(StringBuffer s = new StringBuffer("Hello"))的方式来初始化。

         String字符串修改实现的原理如下:当用String类型对字符串进行修改时,其实现方法是首先创建一个StringBuffer,其次调用StringBuffer的append()方法,最后调用StringBuffer的toString()方法把结果返回。实例如下:

 

String s = "Hello";
s += "World";
以上代码等价于下属代码:
StringBuffer sb = new StringBuffer(s);
s.append("World");
s = sb.toString();

         由此可以看出,上述过程比使用StringBuffer多了一些附加的操作,同时也生成了一些临时的对象,从而导致程序的执行小效率降低。

再说说字符串常量池

      我们在编写代码时String频繁被使用到,Java为了避免在一个系统中产生大量的String对象,引入了字符串常量池。

      创建一个字符串时,首先会检查池中是否有值相同的字符串对象,如果有就直接返回引用,不会创建字符串对象;如果没有则新建字符串对象,返回对象引用,并且将新创建的对象放入池中。但是,通过new方法创建的String对象是不检查字符串常量池的,而是直接在堆中创建新对象,也不会把对象放入池中。上述原则只适用于直接给String对象引用赋值的情况。

String str1 = new String("a"); //不检查字符串常量池的

String str2 = "bb"; //检查字符串常量池的

 

2.StringBuilder和StringBuffer的区别

        StringBuilder也是可以被修饰的字符串,属可变类,它与StringBuffer类似,都是字符串缓冲区,但StringBuilder不是线程安全的,StringBuffer是线程安全的,如果只是在单线程中使用字符串缓冲区,那么StringBuilder的效率会更高些。因此在只有单线程访问时可以使用StringBuilder,当有多个线程访问时,最好使用线程安全的StringBuffer。

        StringBuffer就是为了解决大量拼接字符串时产生很多中间对象问题(指的是String)而提供的一个类,提供append和add方法,可以将字符串添加到已有序列的末尾或指定位置,它的本质是一个线程安全的可修改的字符序列,把所有修改数据的方法都加上了synchronized。但是保证了线程安全是需要性能的代价的。

        在很多情况下我们的字符串拼接操作不需要线程安全,这时候StringBuilder登场了,StringBuilder是JDK1.5发布的,它和StringBuffer本质上没什么区别,就是去掉了保证线程安全的那部分,减少了开销。

StringBuffer 和 StringBuilder 二者都继承了 AbstractStringBuilder ,底层都是利用可修改的char数组(JDK 9 以后是 byte数组)。

总结

         在执行效率方面,StringBuilder最高,StringBuffer次之,String最低,鉴于这一情况,一般而言,如果操作量数据量比较小,应优先使用String类;如果是在单线程下操作大量数据,应优先使用StringBuilder类;如果是在多线程下操作大量数据,应优先考虑StringBuffer类。

(1)在字符串不经常发生变化的业务场景优先使用String(代码更清晰简洁)。如常量的声明,少量的字符串操作(拼接,删除等)。

(2)在单线程情况下,如有大量的字符串操作情况,应该使用StringBuilder来操作字符串。不能使用String"+"来拼接而是使用,避免产生大量无用的中间对象,耗费空间且执行效率低下(新建对象、回收对象花费大量时间)。如JSON的封装等。

(3)在多线程情况下,如有大量的字符串操作情况,应该使用StringBuffer。如HTTP参数解析和封装等。

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值