我看JAVA 之 String

我看JAVA 之 String

注:基於jdk11

String

在java語言中用來表示字符串,所有的字符串(比如“abc”)都String的實例對象。
String是常量,一旦創建不可以被修改,可以使用StringBuffer創建可變字符串。
String類提供了字符串比較,查找,拷貝,大小寫轉換等操作。大小寫轉換基於標準的Unicode.  
字符串拼接”+”:根據不同版本的jdk會有不同實現,如StringBuilder、StringBuffer、StringConcatFactory(invokeDynamic)

實現瞭如下接口

1. java.io.Serializable
2. Comparable<String>
3. CharSequence 提供對字符數組多種只讀形式的統一訪問方法規範

幾個重點的成員變量

/**
 * jdk9開始使用byte[]存儲字符串,1.8及之前使用char[]保存
 */
@Stable
private final byte[] value;

/**
 *  coder用來表示此字符串使用的編碼,coder=0使用LATIN1,coder=1使用UTF16
 *
 *  LATIN1 是8比特的字符集,定義了256個字符。前128個字符與ASCII完全一致,即爲ASCII的超集
 *  UTF16  是可變長度編碼。可以是一個或二個16比特。
 *  根據不同的編碼由不同的工具類實現String的內部編碼,Latin1對應StringLatin1,UTF16對應StringUTF16
 *
 */
private final byte coder;

/** Cache the hash code for the string */
private int hash; // Default to 0

/** use serialVersionUID from JDK 1.0.2 for interoperability */
private static final long serialVersionUID = -6849794470754667710L;

/**
 * 如果關閉壓縮,字符串的bytes使用UTF16編碼
 *
 * 如下爲jit優化方面,爲什麼不直接初始化COMPACT_STRINGS的值:
 *
 * The instance field value is generally opaque to optimizing JIT
 * compilers. Therefore, in performance-sensitive place, an explicit
 * check of the static boolean {@code COMPACT_STRINGS} is done first
 * before checking the {@code coder} field since the static boolean
 * {@code COMPACT_STRINGS} would be constant folded away by an
 * optimizing JIT compiler. The idioms for these cases are as follows.
 *
 * For code such as:
 *
 *    if (coder == LATIN1) { ... }
 *
 * can be written more optimally as
 *
 *    if (coder() == LATIN1) { ... }
 *
 * or:
 *
 *    if (COMPACT_STRINGS && coder == LATIN1) { ... }
 *
 * An optimizing JIT compiler can fold the above conditional as:
 *
 *    COMPACT_STRINGS == true  => if (coder == LATIN1) { ... }
 *    COMPACT_STRINGS == false => if (false)           { ... }
 *
 * @implNote
 * The actual value for this field is injected by JVM. The static
 * initialization block is used to set the value here to communicate
 * that this static final field is not statically foldable, and to
 * avoid any possible circular dependency during vm initialization.
 * 事實上,COMPACT_STRINGS的值是由JVM填充的
 */
static final boolean COMPACT_STRINGS;

static {
    COMPACT_STRINGS = true;
}

/**
 * Class String is special cased within the Serialization Stream Protocol.
 *
 * A String instance is written into an ObjectOutputStream according to
 * <a href="{@docRoot}/../specs/serialization/protocol.html#stream-elements">
 * Object Serialization Specification, Section 6.2, "Stream Elements"</a>
 */
private static final ObjectStreamField[] serialPersistentFields =
    new ObjectStreamField[0];
    
@Native static final byte LATIN1 = 0;
@Native static final byte UTF16  = 1;

幾個重要的方法

    
    1. getBytes()相關
    /**
    *  getBytes() 將當前字符串轉換爲當前文件系統默認編碼格式的字節數組
    *  getBytes(charset) 將當前字符串轉換爲指定編碼格式的字節數組
    */
    public byte[] getBytes(String charsetName)
            throws UnsupportedEncodingException {
        if (charsetName == null) throw new NullPointerException();
        return StringCoding.encode(charsetName, coder(), value);
    }
    public byte[] getBytes(Charset charset) {
        if (charset == null) throw new NullPointerException();
        return StringCoding.encode(charset, coder(), value);
     }
    public byte[] getBytes() {
        return StringCoding.encode(coder(), value);
    }
    2. length()
    /**
    * 返回當前字符串長度,如果是LATIN1字符串長度等於LATIN1格式字節數組長度,否則需要取value.length>>1,長度減半
    */
    public int length() {
        return value.length >> coder();
    }
    3. native intern()
    /**
     * 當調用intern方法時,如果常量池中已經存在equal當前String的對象,那麼返回String常量池中的字符串。
     * 否則,當前String對象會被添加到String常量池並且返回常量池中的String對象引用
     * 如果a.intern() == b.intern(),那麼a.equal(b) == true
     */
    public native String intern();

幾個重要的工具類

1. StringLatin1 提供了啓用壓縮編碼Latin1的情況下的一些常用操作如indexOf、hashcode、replace、trim、strip、compare等
2. StringUTF16 提供了編碼爲UTF16的情況下的一些常用操作如indexOf、hashcode、replace、trim、strip、compare等
3. StringCoding 提供了爲String編解碼decode & encode操作
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章