String、StirngBuffer、StringBuilder的区别《区别|CSDN创作打卡》

String、StirngBuffer、StringBuilder的区别?

类型 可变性 线程安全性 性能分析
String 不可变 String是不可变的那自然没有线程安全的讲究 在字符串的拼接上面,两者都是比String更快。
StirngBuffer 可变 线程安全 (Synchronized修饰)
StringBuilder 可变 线程不安全 StringBuilder 的性能要远大于 StringBuffer。
StringBuffer线程安全,StringBuilder线程不安全,底层实现上,其实StringBuffer就是比StringBuilder多加了Synchronized修饰

既然 StringBuffer 是线程安全的,它的所有公开方法都是同步的,StringBuilder 是没有对方法加锁同步的,所以毫无疑问,StringBuilder 的性能要远大于 StringBuffer。然后在字符串的拼接上面,两者都是比String更快的存在,通过分析jvm解析class所产生的字节码,会发现String的拼接其实是每次都产生新的StringBuilder对象然后toString返回String,因为底层也会对String的效率方面做考虑。所以多次的对象创建拼接,自然而然是比不过只创建一次对象的。

这里应该会有小伙伴好奇,为什么String是不可变呢?

不可变对象的意思就是说:不能改变对象内的成员变量,包括基本数据类型的值不能改变,引用类型的变量不能指向其他的对象,引用类型指向的对象的状态也不能改变

String不可变是因为:

1、字符串常量池的需要,如果字符串可变,改变一个对象会影响到另外一个独立的对象。不变这也是字符串常量池存在的前提条件。

2、Java中String对象的哈希码被频繁地使用,比如在HashMap等容器中。不变性也保证了hash码的唯一性,不需要重新计算,这就让字符串很适合作为Map的键。

3、安全性,确保String在当做参数传递时保持不变,避免安全隐患。比如在数据库用户名、密码、访问路径等传输过程中的保持不变,或者在socket编程中主机名和端口名都是以字符串形式传入的,因为字符串是不可变,所以它的值也是不可变的。防止黑客们可以钻到空子改变字符串的指向的对象值造成安全漏洞。

/**
 * @author hwx
 * @date 2022/1/16 - 14:51
 */
 // 安全性,确保String在当做参数传递时保持不变,避免安全隐患
public class test {
    
    
    public static String appendStr(String s) {
    
    
        s = s + "bbb";
        return s;
    }
    public static void main(String[] args) {
    
    
        //String做参数
        String s= "aaa";
        test.appendStr(s);
        System.out.println("String aaa >>> "+s); //String aaa >>> aaa
        //因为Java对象参数传的是引用,所以不可变的的String参数就被没有改变。
    }
}

4、由于字符串变量不可变,在多线程中可以被共享使用。这样就不用因为线程安全问题而使用同步

使用场景

(1)如果要操作少量的数据用 String;
(2)多线程操作字符串缓冲区下操作大量数据 StringBuffer;StringBuffer 适用于用在多线程操作同一个 StringBuffer 的场景
(3)单线程操作字符串缓冲区下操作大量数据 StringBuilder。如果是单线程场合 StringBuilder 更适合。

猜你喜欢

转载自blog.csdn.net/weixin_46015018/article/details/122558020