閱讀988 返回首頁    go 阿裏雲 go 技術社區[雲棲]


String源碼簡析

類和接口

String類被定義成public final class,所以String類無法被繼承。

String類實現了Serializabel、Comparabe、CharSequence三個接口,分別對應著序列化、排序、字符串處理三個方麵的功能。

類屬性

String類底層有固定長度的字符數組組成,用hash的方法緩存字符串,含有一個序列化ID以及一個用於序列化的ObjectStreamField類,這個類我們會單獨拿出一篇文章來講。

private final char value[];
private int hash;
private static final long seriaVersionUID = -6849794470754667710L;
private static final ObjectStreamField[] serialPersistentFields =
            new ObjectStreamField[0];


類方法

構造方法

String構造數據的構造方法有很多實現方法。

默認構造方法

public String();

新建一個單個字符的char數組。常見於String str = new String();

帶參構造方法

public String(String original);

String類型的傳參直接賦值

public String(char value[]);

char數組則使用Arrays來直接拷貝,當然,可以在傳參的時候,可以再加上位移量和長度(數量),詳見String的源碼

public String(int[] codePoint, int offset, int count);
public String(byte ascii[], int hibyte, int offset, int count);
public String(byte bytes[], Charset charset);
public String(byte bytes[], int offset, int length);
public String(byte bytes[]);

一些byte及編碼類型的傳參不再贅述。

public String(StringBuffer buffer);
public String(StringBuilder builder);

JDK1.5之後,String可以通過StringBuffer和StringBuilder調用Arrays.copyOf()來初始化String。其中,StringBuffer在調用的時候,會加鎖以保證線程安全。

一般方法

字符操作length()isEmpty()charAt()codePointAt()codePointBefore()codePointCount()getBytes() 方法功能同名。

public boolean equals(Object anObject);
public boolean equalsIgnoreCase(String anotherString); // 大小寫不敏感
  • String是final對象,所以在寫equals方法時,是在比較String的各位char數值。
  • String是不可變對象,所以該方法沒有涉及線程相關的設計。
public boolean contentEquals(StringBuffer sb);
public boolean contentEquals(CharSequence cs);
  • equals()方法隻能比較String,而contentEquals的比較類型更多
  • contentEquals針對StringBuffer、StringBuilder、String、Charsequence有著不同的比較方法。
  • StringBuffer多加了一個synchronnized來保證線程安全。
  • contentEquals功能同名,隻比較內容,而忽略類型。
public int compareTo(String anotherString);

按字典序列比較內容,返回不同字符處的距離或不同字符串長度,相等返回0

內部類 CaseInsensitiveComparator

我們發現內部類CaseInsensitiveComparator的compare比較方法為了實現大小寫不敏感,把字符分別toUppperCasetoLowerCase比較了一遍,

一般方法

public boolean regionMatches(int toffset, String other, int ooffset,int len);
public boolean regionMatches(boolean ignoreCase, int toffset, String other, int ooffset, int len);

比較兩個字符串從某處開始的特定長度的字串是否相等。

public String concat(String str);

concact是拚接函數,其中為了設計char數組的拷貝,使用了傳入String對象的getChars()方法。

void getChars(char dst[], int dstBegin) {
    System.arraycopy(value, 0, dst, dstBegin, value.length);
}

在這個函數中,使用了System的arraycopy方法,把當前字符串拷貝到傳入字符串數組的結尾。

最後,concat返回一個新的String對象

public String replace(char oldChar, char newChar) {
    if (oldChar != newChar) {
        int len = value.length;
        int i = -1;
        char[] val = value; /* avoid getfield opcode */

        while (++i < len) {
            if (val[i] == oldChar) {
                break;
            }
        }
        if (i < len) {
            char buf[] = new char[len];
            for (int j = 0; j < i; j++) {
                buf[j] = val[j];
            }
            while (i < len) {
                char c = val[i];
                buf[i] = (c == oldChar) ? newChar : c;
                i++;
            }
            return new String(buf, true);
        }
    }
    return this;
}

replace方法用於返回一個替換字符串,但是這個方法重複執行了部分的循環操作。第一個循環用於找到第一個匹配的字符的位置,之後,再從頭到此位置進行替換,最後從該位置之後再判斷。這樣做的目的是什麼呢?

  • Java是高地址存低位,低地址存高

最後更新:2017-08-21 17:32:40

  上一篇:go  PostgreSQL服務器管理:管理數據庫
  下一篇:go  PostgreSQL服務器管理:數據庫角色