String、StringBuffer、StringBuilder有什么区别?

String、StringBuffer、StringBuilder的区别

String是java中很重要的类,它被声明为final类型(除了hash,其他属性都声明为final)。
因为String声明为final,所以会有不可变性,在拼接字符串的时候会产生很多无用的中间对象,如果要大量操作字符串就会对性能有影响。

StringBuffer应运而生,解决字符串拼接的时候那些没用的中间对象。Stringbuffer提供append和insert方法可以将字符串拼接到已有序列的末尾或指定的位置,StringBuffer的本质是在修改数据的时候加上了synchronized,是一个线程安全的可修改的字符序列,但是这种保证线程安全是需要性能为代价的。

JDK1.5之后,StringBuilder出现了,它和StringBuffer在本质上是相同的,StringBuilder取消了StringBuffer的保证线程安全的部分,减少了内存的开销。

日常开发的时候,少量的字符串拼接对内存其实没有多大影响,像

String str = "w"+"z"+"j";

这种没有变量的字符串,在编译的时候就直接合成“wzj”了,然后看常量池里面“wzj”,如果有,就直接引用,如果没有,就直接在常量池中生成,然后返回引用。

String a = "w";
String str = a+"z"+"j";

这种带有变量的字符串,JDK1.8之后,JVM会帮我们优化,使用StringBuffer.append来拼接。但是这又有一个缺点,如果有大量的字符串拼接,就会new好多次StringBuffer,因此在频繁的字符串操作时,还是使用StringBuilder。

字符串常量池

String在我们的代码中会频繁地使用到,java为了避免在一个系统中产生大量的String对象,引入了字符串常量池。
当我们创建一个字符串的时候,首先会从常量池中检查是否有相同的字符串对象,如果有,就直接返回引用,如果没有,就新建一个字符串对象,返回引用,然后放入常量池中。

**注意:**通过new方法创建的String对象是不检查字符串常量池的,它会直接在堆中创建新对象,然后把对象放入常量池,相当于创建了两个对象。

总结:

如果是字符串不经常发生变化的业务场景中,我们优先使用String(毕竟好听又好记!!!)
如果是单线程的时候,有大量字符串操作,应该选择StringBuilder。
如果是多线程的时候,有大量字符串操作,应该选择StringBuffer。

题目:

public class ClassTest{
     String str = new String("hello");
     char[] ch = {'a','b','c'};
     public void fun(String str, char ch[]){
     str="world";
     ch[0]='d';
 }
 public static void main(String[] args) {
     ClassTest test1 = new ClassTest();
     test1.fun(test1.str,test1.ch);
     System.out.print(test1.str + " and ");
     System.out.print(test1.ch);
     }
 }

输出结果:hello and dbc

这道题里方法中修改值都是修改形参的值,区别是一个通过形参修改堆值,而另一个仅仅只是修改形参。
详细分析一下:
char[] ch = {‘a’,‘b’,‘c’};是数组,数组存放在堆中,所以当方法通过形参修改值时会去堆中修改。当成员变量ch再去访问时,堆中的值已经修改,所以输出dbc。
而String str = new String(“hello”);会进行两步操作:
1、JVM先在堆中创建一个指定的String对象"hello",并让str引用指向该对象。
2、JVM会在常量池中 寻找或新建 一个”hello”,并让堆中对象与之关联。
所以当方法为形参赋值时(str=“world”;),只是为形参在常量池中新建一个”world”并引用,也只修改了形参,成员变量str本身未被修改。
所以,当new了除封装类型以外的对象时,即便通过形参修改对象内部的值也会去堆中修改。
所以,当String str = new String(“hello”);时产生了一个String对象,如果常量池没有"hello"常量还会产生一个"hello"常量。

你可能感兴趣的:(java基础,String,StringBuffer,StringBuilder,字符串常量池)