Java基础知识——StringStringBuilderStringBuffer的区别

    技术2022-07-10  163

    Java基础——String/StringBuilder/StringBuffer的区别

    1. String

    public final class String implements java.io.Serializable, Comparable<String>, Charsequence { ... private final char[] value; ... } String x = "ab"; x += "cd";

    a. JDK 1.8之前,需要三块内存完成操作,一是原来的"ab"字符串内存,一是新拼接来的"cd"字符串内存,一是拷贝两个字符串拼接在一起的新的String对象的字符串的内存;

    b. JDK 1.8之后,编译器会将"+"字符串拼接操作根据需要编译成StringBuilder或者StringBuffer来处理。

    String内部是一个final char[]存储的,被初始化后就不能改变这个数组,对String重新赋值实质上是在heap中重新创建String对象


    2. StringBuilder

    public final class StringBuilder extends AbstractStringBuilder implements java.io.Serializable, Charsequence { }

    StringBuilder的数据是存储在一个char[]中,再不断调用append或者delete方法来增加或删除字符串

    StringBuilder的append方法最终调用的是父类AbstractStringBuilder的append方法 详细添加步骤见下面注释

    abstract class AbstractStringBuilder implements Appendable, CharSequence { char[] value; ... public AbstractStringBuilder append(String str) { if (str == null) // append空字串处理 return appendNull(); // 计算要添加的字串长度 int len = str.length(); // 确保char数组的容量足够,对数组扩容, // 实质是调用Array.copyOf把原来的字串拷贝到新的长度的char[]中 ensureCapacityInternal(count + len); // 将需要append的字符串拷贝到新的value[]的末端 str.getChars(0, len, value, count); // 更新char[]长度 count += len; return this; } }

    3. StringBuffer

    public final class StringBuffer extends AbstractStringBuilder implements java.io.Serializable, CharSequence { // 在toString()时做了优化,如果这个临时的数组不为空就直接使用此数组, // 一旦修改(增删字符)操作,都会被置空,并等下一次toString为它赋值, // 在未修改的情况下再次toString将提高效率 private transient char[] toStringCache; ... } 附:关于transient修饰符(字面意思为临时的) 1. 被此修饰符修饰后,变量将不是对象持久化的一部分,被序列化后无法访问(即transient变量不能被序列化); 2. 只能修饰类的成员变量和静态变量,不能修饰局部变量、方法、类,存在这种修饰的变量的类必须实现Serializable接口; 3. transient变量不能被反序列化(很好理解,本身不能被序列化,序列化后再反序列化自然不能得到之前的值了) 所以这个临时的变量就是在序列化前可用,序列化后,序列化再反序列化都不可用了。

    StringBuffer与StringBuilder的区别是:

    StringBuffer在创建时,自带了长度16,有初始字符串也会在字串长度基础上加16StringBuffer是线程安全的,方法都是同步方法,适用于多线程共享的变量,在性能上为了保证同步会有所牺牲。
    Processed: 0.008, SQL: 9