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比較方法為了實現大小寫不敏感,把字符分別toUppperCase
和toLowerCase
比較了一遍,
一般方法
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