JDK源碼之String
1、String類簡介
String類是日常開發中很常用,該類用關鍵字final修飾,說明String類不能夠被繼承,里面的方法不能被重寫,String是不可變的。String類實現了Comparable<String>和CharSequence
接口,提供了字符串比較、獲取字符串長度等方法。
2、源碼
2.1、String類的屬性
public final class String implements java.io.Serializable, Comparable<String>, CharSequence { /** 存儲字符串的字符數組*/ private final char value[]; /** Cache the hash code for the string */
//用于存放字符串的hashCode碼,第一次調用hashCode()函數的時候計算并緩存起來,之后再調用hashCode()函數時直接沖緩存中獲取,不用再次計算 private int hash; // Default to 0 /** use serialVersionUID from JDK 1.0.2 for interoperability */ private static final long serialVersionUID = -6849794470754667710L; /** * Class String is special cased within the Serialization Stream Protocol. * * A String instance is written into an ObjectOutputStream according to * <a href="{@docRoot}/../platform/serialization/spec/output.html"> * Object Serialization Specification, Section 6.2, "Stream Elements"</a> */
/用于自定義序列化 private static final ObjectStreamField[] serialPersistentFields = new ObjectStreamField[0]; }
2.2、String類構造方法
public String() { this.value = "".value; } public String(String original) { this.value = original.value; this.hash = original.hash; } public String(char value[]) { this.value = Arrays.copyOf(value, value.length); } public String(char value[], int offset, int count) { if (offset < 0) { throw new StringIndexOutOfBoundsException(offset); } if (count <= 0) { if (count < 0) { throw new StringIndexOutOfBoundsException(count); } if (offset <= value.length) { this.value = "".value; return; } } // Note: offset or count might be near -1>>>1. if (offset > value.length - count) { throw new StringIndexOutOfBoundsException(offset + count); } this.value = Arrays.copyOfRange(value, offset, offset+count); } public String(int[] codePoints, int offset, int count) { if (offset < 0) { throw new StringIndexOutOfBoundsException(offset); } if (count <= 0) { if (count < 0) { throw new StringIndexOutOfBoundsException(count); } if (offset <= codePoints.length) { this.value = "".value; return; } } // Note: offset or count might be near -1>>>1. if (offset > codePoints.length - count) { throw new StringIndexOutOfBoundsException(offset + count); } final int end = offset + count; // Pass 1: Compute precise size of char[] int n = count; for (int i = offset; i < end; i++) { int c = codePoints[i]; if (Character.isBmpCodePoint(c)) continue; else if (Character.isValidCodePoint(c)) n++; else throw new IllegalArgumentException(Integer.toString(c)); } // Pass 2: Allocate and fill in char[] final char[] v = new char[n]; for (int i = offset, j = 0; i < end; i++, j++) { int c = codePoints[i]; if (Character.isBmpCodePoint(c)) v[j] = (char)c; else Character.toSurrogates(c, v, j++); } this.value = v; } @Deprecated public String(byte ascii[], int hibyte, int offset, int count) { checkBounds(ascii, offset, count); char value[] = new char[count]; if (hibyte == 0) { for (int i = count; i-- > 0;) { value[i] = (char)(ascii[i + offset] & 0xff); } } else { hibyte <<= 8; for (int i = count; i-- > 0;) { value[i] = (char)(hibyte | (ascii[i + offset] & 0xff)); } } this.value = value; } @Deprecated public String(byte ascii[], int hibyte) { this(ascii, hibyte, 0, ascii.length); } public String(byte bytes[], int offset, int length, String charsetName) throws UnsupportedEncodingException { if (charsetName == null) throw new NullPointerException("charsetName"); checkBounds(bytes, offset, length); this.value = StringCoding.decode(charsetName, bytes, offset, length); } public String(byte bytes[], int offset, int length, Charset charset) { if (charset == null) throw new NullPointerException("charset"); checkBounds(bytes, offset, length); this.value = StringCoding.decode(charset, bytes, offset, length); } public String(byte bytes[], String charsetName) throws UnsupportedEncodingException { this(bytes, 0, bytes.length, charsetName); } public String(byte bytes[], Charset charset) { this(bytes, 0, bytes.length, charset); } public String(byte bytes[], int offset, int length) { checkBounds(bytes, offset, length); this.value = StringCoding.decode(bytes, offset, length); } public String(byte bytes[]) { this(bytes, 0, bytes.length); } public String(StringBuffer buffer) { synchronized(buffer) { this.value = Arrays.copyOf(buffer.getValue(), buffer.length()); } } public String(StringBuilder builder) { this.value = Arrays.copyOf(builder.getValue(), builder.length()); } String(char[] value, boolean share) { // assert share : "unshared not supported"; this.value = value; }
2.3、String類常用方法
- 判斷字符串是否為空
public boolean isEmpty() {
//根據字符串數組的長度判斷char value[]的長度 return value.length == 0; }
- 獲取字符串的長度
public int length() {
//返回char value[]的長度
return value.length;
}
- 獲取特定位數的字符
public char charAt(int index) {
//檢查傳入的位置是否小于0或者大于數組長度 if ((index < 0) || (index >= value.length)) { throw new StringIndexOutOfBoundsException(index); }
//返回傳入位置的字符 return value[index]; }
- equals方法,重寫Object類的equals方法,源碼注釋可以看上一篇Obejct類源碼:http://www.rzrgm.cn/buaaczw/p/19026050
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String)anObject;
int n = value.length;
if (n == anotherString.value.length) {
char v1[] = value;
char v2[] = anotherString.value;
int i = 0;
while (n-- != 0) {
if (v1[i] != v2[i])
return false;
i++;
}
return true;
}
}
return false;
}
- 復制字符串到目標數組中,從destBegin開始
void getChars(char dst[], int dstBegin) { System.arraycopy(value, 0, dst, dstBegin, value.length); }
- 獲取字符串的字節數組,可指定字符集或者不指定字符集
public byte[] getBytes(String charsetName) throws UnsupportedEncodingException { if (charsetName == null) throw new NullPointerException(); return StringCoding.encode(charsetName, value, 0, value.length); } public byte[] getBytes(Charset charset) { if (charset == null) throw new NullPointerException(); return StringCoding.encode(charset, value, 0, value.length); } public byte[] getBytes() { return StringCoding.encode(value, 0, value.length); }
- 忽略大小寫的equals
public boolean equalsIgnoreCase(String anotherString) { return (this == anotherString) ? true : (anotherString != null) && (anotherString.value.length == value.length)
//帶偏移量的忽略大小寫的equals && regionMatches(true, 0, anotherString, 0, value.length); }
- 帶偏移量的忽略大小寫的equals
- ignoreCase:是否忽略大小寫 true-忽略 fale-不忽略
- toffset:當前字符串的偏移量
- other:需要比較的字符串
- ooffset:需要比較的字符串的偏移量
- len:需要比較的字符長度
public boolean regionMatches(boolean ignoreCase, int toffset, String other, int ooffset, int len) { char ta[] = value; int to = toffset; char pa[] = other.value; int po = ooffset; // Note: toffset, ooffset, or len might be near -1>>>1. if ((ooffset < 0) || (toffset < 0) || (toffset > (long)value.length - len) || (ooffset > (long)other.value.length - len)) { return false; } while (len-- > 0) { char c1 = ta[to++]; char c2 = pa[po++]; if (c1 == c2) { continue; } if (ignoreCase) { // If characters don't match but case may be ignored, // try converting both characters to uppercase. // If the results match, then the comparison scan should // continue. char u1 = Character.toUpperCase(c1); char u2 = Character.toUpperCase(c2); if (u1 == u2) { continue; } // Unfortunately, conversion to uppercase does not work properly // for the Georgian alphabet, which has strange rules about case // conversion. So we need to make one last check before // exiting. if (Character.toLowerCase(u1) == Character.toLowerCase(u2)) { continue; } } return false; } return true; }
- 字符串截取
- beginIndex : 起始位置
- endIndex:結束位置
public String substring(int beginIndex) { if (beginIndex < 0) { throw new StringIndexOutOfBoundsException(beginIndex); } int subLen = value.length - beginIndex; if (subLen < 0) { throw new StringIndexOutOfBoundsException(subLen); } return (beginIndex == 0) ? this : new String(value, beginIndex, subLen); } public String substring(int beginIndex, int endIndex) { if (beginIndex < 0) { throw new StringIndexOutOfBoundsException(beginIndex); } if (endIndex > value.length) { throw new StringIndexOutOfBoundsException(endIndex); } int subLen = endIndex - beginIndex; if (subLen < 0) { throw new StringIndexOutOfBoundsException(subLen); } return ((beginIndex == 0) && (endIndex == value.length)) ? this : new String(value, beginIndex, subLen); }
- 字符串比較
public int compareTo(String anotherString) {
//字符串長度 int len1 = value.length;
//被比較的字符串長度 int len2 = anotherString.value.length;
//取兩個字符串中的最小值 int lim = Math.min(len1, len2); char v1[] = value; char v2[] = anotherString.value; int k = 0; while (k < lim) { char c1 = v1[k]; char c2 = v2[k]; if (c1 != c2) {
// 返回結果 return c1 - c2; } k++; }
//如果字符串是包含關系,則比較長度 return len1 - len2; }

浙公網安備 33010602011771號