美文网首页
Java·String、StringBuilder、String

Java·String、StringBuilder、String

作者: Sarahhhh | 来源:发表于2019-03-28 15:01 被阅读0次

    1.String

    String类的基本字段(field)

    Java9之后,String中用byte[]存储字符串,并用coder表示该字符串使用哪种编码。
    coder主要是为了适应不同语言字符的需要,有的字符需要2字节编码,有的只需要1字节,coder就表示这个字符串应当使用哪种编码规则。这样在存储像英文一样只需要一个字节的字符时,可以压缩空间。coder有LATIN1(1字节)和UTF16(2字节)两种选项,相关的还有COMPACT_STRINGS,为true表示这个字符串是压缩的。编码这块由JVM处理。

    public final class String
        implements java.io.Serializable, Comparable<String>, CharSequence {
        /** The value is used for character storage. */
        private final byte[] value;
    
        /** The identifier of the encoding used to encode the bytes in {@code value}. */
        private final byte coder;
    
        static final boolean COMPACT_STRINGS;
        static {
            COMPACT_STRINGS = true;
        }
    
        /** Cache the hash code for the string */
        private int hash; // Default to 0
    }
    

    不可变的String

    String类是final的,存储的byte[]也是final的,所以保证String不可变。
    不可变的好处

    1. 可以缓存hash值
    2. String Pool 的需要
    3. 帮助其他Objects的使用
      • 例如Set<String>中,如果String可变,改变后的String可能违反set规则
    4. 安全性
      • 例如在作为网络连接参数时,保证String不可变更具安全性
    5. 线程安全

    Program Creek : Why String is immutable in Java?

    构造函数

    在将一个字符串对象作为另一个字符串对象的构造函数参数时,并不会完全复制 value 数组内容,而是都会指向同一个 value 数组

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

    Java基础-String

    2. StringBuilder和StringBuffer

    和String一样用byte[]存储,也有coder成员。但是这两个都是可变的,类内部提供append()之类的修改字符串的方法。
    二者都继承自AbstractStringBuilder,其实相差不大,主要是StringBuffer中很多方法都被关键字synchronized修饰,因此StringBuffer是线程安全的,而StringBuilder是线程不安全的。也因此,但单线程的情况下, StringBuilder的性能要比StringBuffer更好。
    如果要对一个字符串做频繁修改,最好用StringBuilder,如果是在多线程的情况下(变量可能被多个线程访问),最好用StringBuffer。

    Java 之 synchronized 详解
    深入理解Java并发之synchronized实现原理

    3. StringPool 字符串常量池

    String Pool保存着所有字符串字面量(literal strings),这些字面量在编译时期就确定。可以使用 String 的 intern() 方法在运行过程中将字符串添加到 String Pool 中。
    intern()
    当一个字符串调用 intern() 方法时,如果 String Pool 中已经存在一个字符串和该字符串值相等(使用 equals() 方法进行确定),那么就会返回 String Pool 中字符串的引用;否则,就会在 String Pool 中添加一个新的字符串,并返回这个新字符串的引用。

    String s1 = "hello";  //用字面量创建字符串,会自动将字符串放入 String Pool 中
    String s2 = s1.intern(); //返回的是常量池中"Hello"字符串的引用
    

    String Pool是一个固定大小的Hashtable,默认值大小长度是1009,如果放进String Pool的String非常多,就会造成Hash冲突严重,从而导致链表会很长,而链表长了后直接会造成的影响就是当调用 String.intern() 时性能会大幅下降。在jdk7中,StringTable的长度可以通过一个参数指定:XX:StringTableSize=99991

    深入解析 String#intern

    相关文章

      网友评论

          本文标题:Java·String、StringBuilder、String

          本文链接:https://www.haomeiwen.com/subject/vgafbqtx.html