Java String 、 StringBuffer 、StringBuilder类的关系和区别

来源:互联网 发布:linux 自动运行脚本 编辑:程序博客网 时间:2024/05/27 20:33
String的值是不可变的,这就导致每次对String的操作都会生成新的String对象,不仅效率低下,而且大量浪费有限的内存空间,StringBuffer是可变类,和线程安全的字符串操作类,任何对它指向的字符串的操作都不会产生新的对象,StringBuffer和StringBuilder类功能基本相似
1. String 类 

  String的值是不可变的,这就导致每次对String的操作都会生成新的String对象,不仅效率低下,而且大量浪费有限的内存空间。 
String a = "a"; //假设a指向地址0x0001 
a = "b";//重新赋值后a指向地址0x0002,但0x0001地址中保存的"a"依旧存在,但已经不再是a所指向的,a 已经指向了其它地址。 
因此String的操作都是改变赋值地址而不是改变值操作。 

2. StringBuffer是可变类且线程安全的字符串操作类,任何对它指向的字符串的操作都不会产生新的对象。 每个StringBuffer对象都有一定的缓冲区容量,当字符串大小没有超过容量时,不会分配新的容量,当字符串大小超过容量时,会自动增加容量。 

StringBuffer buf=new StringBuffer(); //分配长16字节的字符缓冲区 
StringBuffer buf=new StringBuffer(512); //分配长512字节的字符缓冲区 
StringBuffer buf=new StringBuffer("this is a test")//在缓冲区中存放了字符串,并在后面预留了16字节的空缓冲区。 

3.StringBuilder
  StringBuffer和StringBuilder类功能基本相似,主要区别在于StringBuffer类的方法是多线程、安全的,而StringBuilder不是线程安全的,相比而言,StringBuilder类会略微快一点。对于经常要改变值的字符串应该使用StringBuffer和StringBuilder类。 

4.线程安全 
StringBuffer 线程安全 
StringBuilder 线程不安全 

5.速度 
一般情况下,速度从快到慢:StringBuilder>StringBuffer>String,这种比较是相对的,不是绝对的。 

6.总结 
(1).如果要操作少量的数据用 = String 
(2).单线程操作字符串缓冲区 下操作大量数据 = StringBuilder 
(3).多线程操作字符串缓冲区 下操作大量数据 = StringBuffer 
(4)在StringBuffer与StringBuilder中都有.toString()的方法将其转换为String,这是在实际应用中经常用到的。

一个值得注意很容易忽略的问题,看下面代码:
public class Demo{public static void main(String[] args) { StringBuilder sb1=new StringBuilder("strBuilder"); StringBuilder sb2=new StringBuilder("strBuilder"); String s1 = new String("str"); String s2 = new String("str"); System.out.println("StringBuilder的equals结果:" + sb2.equals(sb1)); System.out.println("StringBuilder的equals结果:" + s2.equals(s1)); System.out.println("StringBuilder的toString()比较结果:" 
+ sb2.toString().equals(sb1.toString()));}}

运行结果:

StringBuilder的equals结果:false
StringBuilder的equals结果:true
StringBuilder的toString()比较结果:true

说明:String类里重写了equals()方法,使其之比较字符串的内容,所以结果为true;但是StringBuilder类并没有重写equals()方法,所以默认比较的是存储地址,又因为sb1、sb2尽管其内容相同,但实际上是两个对象,其存储的位置可定不相同,所以结果为false。在根据上面所说的toString ()方法将StringBuilder对象转换成String对象进行比较,这时比较的是内容,所以结果为true。public class Demo{

对于StringBuffer,有一点容易被忽略,值得注意:
public static void main(String[] args) {StringBuffer sbf = new StringBuffer("hello");//System.out.printf(sbf);  //错误!(无法通过方法调用转换将实际参数StringBuffer转换为String)System.out.printf(sbf.toString());}}
在StringBuffer里面没有方法可以直接打印StringBuffer对象的内容,一般是调用toString()方法进行转换。