5.String、StringBuffer、StringBuilder的区别

第5讲:String、StringBuffer、StringBuilder有什么区别?

典型回答:
  • 都是final类,都不允许被继承。
  • String 是Java语言非常基础和重要的类,提供了构造和管理字符串的各种基本逻辑。它是
    典型的Immutable类,被声明成为finalclass,所有属性也都是final的。也由于它的不可
    变性,类似拼接、裁剪字符串等动作,都会产生新的String对象。由于字符串操作的普遍性,
    所以相关操作的效率往往对应用性能有明显影响。
  • StringBuffer是为解决上面提到拼接产生太多中间对象的问题而提供的一个类,它是Java
    1.5中新增的,我们可以用append或者add方法,把字符串添加到已有序列的末尾或者
    指定位置。StringBuffer本质是一个线程安全的可修改字符序列,它保证了线程安全,也随
    之带来了额外的性能开销,所以除非有线程安全的需要,不然还是推荐使用它的后继者,也
    就是StringBuilder。
  • StringBuilder在能力上和StringBuffer没有本质区别,但是它去掉了线程安全的部分,有效
    减小了开销,是绝大部分情况下进行字符串拼接的首选。
扩展知识
1.字符串的设计和实现考量
  • String是Immutable类的典型实现,原生的保证了基础线程安全,因为无法对它内部数据进行任何修改,这种便利甚至体现在拷贝构造函数中,由于不可变,Immutable对象在拷贝时不需要额外复制数据。
  • StringBuffer实现的一些细节,它的线程安全是通过把各种修改数据的方法都加上synchronized关键字实现的,非常直白。其实,这种简单粗暴的实现方式,非常适合我们常见的线程安全类实现,不必纠结于synchronized性能之类。为了实现修改字符序列的目的,StringBuffer和StringBuilder底层都是利用可修改的
    (char,JDK9以后是byte)数组,二者都继承了AbstractStringBuilder,里面包含了基本操作,区别仅在于最终的方法是否加了synchronized。
  • StringBuffer和StringBuilder构建时初始字符串长度加16(这意味着,如果没有构建对象时输入最初的字符串,那么初始值就是16)。我们如果确定拼接会发生非常多次,而且大概是可预计的,那么就可以指定合适的大小,避免很多次扩容的开销。扩容会产生多重开销,因为要抛弃原有数组,创建新的(可以简单认为是倍数)数组,还要进行arraycopy。
StringstrByBuilder =new
StringBuilder().append("aa").append("bb").append("cc").append
("dd").toString();
String strByConcat="aa"+"bb"+"cc"+"dd";//Java语言为字符串连接运算符(+)提供特殊支持,并为其他对象转换为字符串。 字符串连接是通过StringBuilder (或StringBuffer )类及其append方法实现的。
2.字符串的缓存

针对常量池的优化。当2个String对象拥有相同的值时,他们只引用常量池中的同一个拷贝。当同一个字符串反复出现时,这个技术可以大幅度节省内存空间。

String str1="爱慕课";
String str2="爱慕课";
System.out.println(str1==str2);
//多次出现的字符常量,java编译器只创建一个,所以返回true,因为两者都是在字符串常量池中(由于初始化就会在此区域分布内存)而常量池中的有个与栈区类似的特性,就是当str2指向的常量在常量区已存在时,他不会创建新的内存空间来存此常量,而是指向已有常量的内存(应该是以此节约空间)
3.一道典型的选择题
 public static void main(String[] args)
 {
     StringBuffer a=new StringBuffer("A");
     StringBuffer b=new StringBuffer("B");
     operate(a,b);
     System.out.println(a+"."+b); //AB.B
     String aa=new String("A");
     String bb=new String("B");
     operate(aa,bb);
     System.out.println(aa+"."+bb);//A.B
}
static void operate(StringBuffer x,StringBuffer y) {
    x.append(y);
    y=x;
    }   
static void operate(String x,String y) {
    x=x+y;
    y=x;
    }

猜你喜欢

转载自blog.csdn.net/endlessseaofcrow/article/details/80318620
今日推荐