Java基础-String类和StringBuffer类的区别。

String类

String类表示的字符串是常量,一旦创建后,字符串的内容和长度都无法改变,并且被声明为final class,不可以被继承,成员属性中除了hash之外都被final修饰,当通过String的构造函数初始化新的String对象时,也只是根据传入的引用对象的value和hashcode进行了赋值。下面是String的部分源码。

public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence {
    private final char value[];
    private int hash; // Default to 0

     public String() {
        this.value = new char[0];
    }

    public String(String original) {
        this.value = original.value;
        this.hash = original.hash;
    }

    public String(char value[]) {
        this.value = Arrays.copyOf(value, value.length);
    }    
    
    ...
}

StringBuffer类

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

StringBuild类

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

字符串常量池

这里顺带介绍一下字符串常量池。由于在我们的代码中String是真的频繁得使用到,Java为了避免在一个系统中产生大量的String对象,引入了字符串常量池。
创建一个字符串时,首先会检查池中是否有值相同的字符串对象,如果有就直接返回引用,不会创建字符串对象;如果没有则新建字符串对象,返回对象引用,并且将新创建的对象放入池中。但是,通过new方法创建的String对象是不检查字符串常量池的,而是直接在堆中创建新对象,也不会把对象放入池中。上述原则只适用于直接给String对象引用赋值的情况。

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

总结

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

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

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

你可能感兴趣的:(Java基础)