Java String、 StringBuffer 和 StringBuilder详解和对比

String类

字符串广泛应用在Java编程中,在Java中字符串属于对象,Java提供了String类来创建和操作字符串。

  • String类是不可改变的,被final修饰的。所以你一旦创建了String对象,那它的值就无法改变了。
    字符串实际上就是一个char数组,并且内部就是封装了一个char数组。 并且char数组是被final修饰的;
    public final class String
        implements java.io.Serializable, Comparable, CharSequence {
        /** The value is used for character storage. */
        private final char value[];
    
    并且String中所有的方法,都是对于char数组的改变,只要是对它的改变,方法内部都是返回一个新的String。
  • 字符串常量池(String Constant Pool,简称SCP)
    从Java 7开始属于堆空间的一部分(以前是放在方法区)
  • 当遇到字符串字面量是,会去查看字符串常量池SCP。
    如果SCP中存在与字面量内容一样的字符串对象A时,就返回A
    否则,创建一个新的字符串对象D,并加入到SCP中,返回D
  • 通过new关键字来生成的字符串都是在堆区进行,这个字符串中的value存储着字符串常量池中的地址。

String类的常见面试问题

  1. 以下打印结果为:
    String s1 = "abc";           
    String s2 = new String("abc");     
    System.out.println(s1==s2);       
    System.out.println(s1.equals(s2));
    
    打印结果:
    false
    true
    
    因为s1是字符串字面量,在常量池中,而s2是通过new创建的,在堆中,所以s1和s2地址不同,但是内容相同。
  2. 以下打印结果为:
    String s1= "a" + "b" + "c";
    String s2= "abc";
    System.out.println(s1==s2);
    System.out.println(s1.equals(s2));
    
    打印结果:
    true
    true
    
    因为s1和s2都是字符串字面量,在常量池中。
  3. 以下打印结果为:
    String s1 = "ab";
    String s2 = "abc";
    String s3 = s1 + "c";
    System.out.println(s3==s2);        
    System.out.println(s3.equals(s2));
    
    打印结果:
    false
    true
    
    先在常量池中创建 ab ,地址指向 s1, 再创建 abc ,指向 s2。对于 s3,先创建StringBuilder(或 StringBuffer)对象,通过 append 连接得到 abc ,再调用 toString() 转换得到的地址指向 s3。故 (s3==s2) 为 false。

StringBuffer类

字符串变量。在进行字符串操作时,不会返回新的字符串常量。
它的方法都加了synchronized关键字,所以它是线程安全的。

StringBuilder类

字符串变量。在进行字符串操作时,不会返回新的字符串常量。
非线程安全,性能上优于StringBuffer

使用基本原则:

  • 如果要操作少量的数据用String;
  • 单线程操作大量数据用StringBuilder;
  • 多线程操作大量数据,用StringBuffer;

你可能感兴趣的:(Java String、 StringBuffer 和 StringBuilder详解和对比)