zoukankan      html  css  js  c++  java
  • String、StringBuilder和StringBuffer的比较

    @

    1.String特性

    1.1 不可变

    它是Immutable类,被声明为final class,所有属性也是final的, 其拼接、裁剪等操作都会产生新的String对象。不可变的主要作用在于当一个对象需要被多线程共享,并且访问频繁时,可以省略同步和锁等待的时间,从而大幅度提高系统性能。不可变模式是一个可以提高多线程程序的性能,降低多线程程序复杂度的设计模式。所以String是原生线程安全的。

    1.2 字符串常量池

    String在Java世界中使用过于频繁,队系统性能的影响权重很大,所以JVM有针对性的优化。为了节约内存空间,防止相同字符串反复出现,避免创建重读字符串,引入了缓存字符串常量池,其机制涉及到String的创建方式。

    1. 通过直接量给String对象引用赋值来创建一个字符串时,JVM首先检查池中是否有值相同的字符串对象,如果有则不需要创建直接从池中刚查找到的对象引用;如果没有则在池中新建字符串对象,返回对象引用,并且将新创建的对象放入池中。
    2. 采用new关键字新建一个字符串对象时,JVM首先检查池中有没有"xyz"这个字符串对象,如果有,则直接在堆中创建一个"xyz"字符串对象 ,不会把对象放入池中。如果没有,则首先在字符串池中创建一个"xyz"字符串对象,然后再在堆中创建一个"xyz"字符串对象
    3. Intern()方法。String提供了inter()显示方法提示JVM缓存字符串。 调用此方法后,如果池已经包含一个等于此String对象的字符串(equals(oject)),则返回池中的字符串。否则,将此String对象添加到池中,并返回此String对象的引用。
    String str1 = "123"; //通过直接量赋值方式,放入字符串常量池  
    String str2 = new String(“123”);//通过new方式赋值方式,不放入字符串常量池
    
    String s3 = new String("xyz");//通过new方式赋值方式,先在常量池创建xyz,再从堆中创建string对象,并将引用付给s3
    String s4 = new String("xyz");//从堆中创建string对象,并将引用付给s4
    System.out.println(s3==s4); //s3 != s4
    

    2.StringBuilder和StringBuffer

    两者都是实现AbstractStringBuilder抽象类,拥有几乎一致对外提供的调用接口。

    2.1 区别

    1. String、StringBuilder和StringBuffer的在内存中的存储方式相同,不同点是StringBufer/StringBuilder对象的值是可以改变的,并且值改变以后,对象引用不会发生改变。
    2. 两者对象在构造过程中,首先按照默认大小申请一个字符数组,由于会不断加入新数据,当超过默认大小后,会创建一个更大的数组,并将原先的数组内容复制过来,再丢弃旧的数组。因此,对于较大对象的扩容会涉及大量的内存复制操作,如果能够预先评估大小,可提升性能。
    3. StringBufer是线程安全的,但是StringBuilder是线程不安全的。StringBufer类中方法定义前面都会有synchronize关键字加锁,性能要远低于StringBuilder。

    2.2 应用场景

    1. 在字符串内容不经常发生变化的业务场景优先使用String类。例如:常量声明、少量的字符串拼接操作等。
    2. 如果有大量的字符串内容拼接,避免使用String与String之间的“+”操作,因为这样会产生大量无用的中间对象,耗费空间且执行效率低下(新建对象、回收对象花费大量时间)。
    3. 在频繁进行字符串的运算(如拼接、替换、删除等),并且运行在多线程环境下,建议使用StringBufer,例如XML解析、HTTP参数解析与封装。运行在单线程环境下,建议使用StringBuilder,例如SQL语句拼装、JSON封装等。

    参考
    《Java核心技术36讲》
    《深入理解JVM虚拟机》

  • 相关阅读:
    java private修饰符的作用域
    debug运行下报错,但不影响运行ERROR: JDWP Unable to get JNI 1.2 environment, jvm->GetEnv() return code = -2(转)
    非线程安全的HashMap 和 线程安全的ConcurrentHashMap(转载)
    【Java集合源码剖析】HashMap源码剖析(转)
    eclipse 解决乱码问题
    java替换txt文本中的字符串
    tomcat startup.bat 启动脚本(转)
    tomcat 点击startup.bat一闪而过
    tomcat 目录文件夹作用(转)
    引脚复用
  • 原文地址:https://www.cnblogs.com/ChengzhiYang/p/12402587.html
Copyright © 2011-2022 走看看