本章原始碼分析基于JDK1.7
實作的介面
String類被final修飾詞修飾,代表不可修改的特性,它實作了三個介面,Serializable是序列化介面,Compareble是排序介面,Char是字符序列介面,
public final class String implements Serializable, Comparable<String>, CharSequence
主要成員變數
char[]:String通過char[]來實作String的各種功能,字串由字符陣列實作,
hash:用于快取hash值,因為String類是final不可修改的,所以hash值也是固定的,為了避免重復計算hash值而快取,
CASE_INSENSITIVE_ORDER:排序器,由上可知String類實作了Compareble介面,這里的Comparator用于忽視大小寫的字串的比較,
private final char[] value;
private int hash;
public static final Comparator<String> CASE_INSENSITIVE_ORDER = new String.CaseInsensitiveComparator();
建構式
String共有15個多載建構式,入參這幾種:空、char[]、String、StringBuffer、StringBuilder、byte[],通過這些來構造字串物件,
//第一種,入參為空,新建了大小為0的char陣列,這就是空字串
public String() {
this.hash32 = 0;
this.value = new char[0];
}
//第二種,入參為String物件,直接將入參的屬性復制過來
public String(String var1) {
this.hash32 = 0;
this.value = var1.value;
this.hash = var1.hash;
}
//第三種,入參為char[],將value賦值為入參var1
public String(char[] var1) {
this.hash32 = 0;
this.value = Arrays.copyOf(var1, var1.length);
}
//第四種,入參為char[],截取char[]中從var2到var3的字符作為字串
public String(char[] var1, int var2, int var3) {
this.hash32 = 0;
if (var2 < 0) {
throw new StringIndexOutOfBoundsException(var2);
} else if (var3 < 0) {
throw new StringIndexOutOfBoundsException(var3);
} else if (var2 > var1.length - var3) {
throw new StringIndexOutOfBoundsException(var2 + var3);
} else {
this.value = Arrays.copyOfRange(var1, var2, var2 + var3);
}
}
public String(int[] var1, int var2, int var3) {
this.hash32 = 0;
if (var2 < 0) {
throw new StringIndexOutOfBoundsException(var2);
} else if (var3 < 0) {
throw new StringIndexOutOfBoundsException(var3);
} else if (var2 > var1.length - var3) {
throw new StringIndexOutOfBoundsException(var2 + var3);
} else {
int var4 = var2 + var3;
int var5 = var3;
int var7;
for(int var6 = var2; var6 < var4; ++var6) {
var7 = var1[var6];
if (!Character.isBmpCodePoint(var7)) {
if (!Character.isValidCodePoint(var7)) {
throw new IllegalArgumentException(Integer.toString(var7));
}
++var5;
}
}
char[] var10 = new char[var5];
var7 = var2;
for(int var8 = 0; var7 < var4; ++var8) {
int var9 = var1[var7];
if (Character.isBmpCodePoint(var9)) {
var10[var8] = (char)var9;
} else {
Character.toSurrogates(var9, var10, var8++);
}
++var7;
}
this.value = var10;
}
}
/** @deprecated */
@Deprecated
public String(byte[] var1, int var2, int var3, int var4) {
this.hash32 = 0;
checkBounds(var1, var3, var4);
char[] var5 = new char[var4];
int var6;
if (var2 == 0) {
for(var6 = var4; var6-- > 0; var5[var6] = (char)(var1[var6 + var3] & 255)) {
;
}
} else {
var2 <<= 8;
for(var6 = var4; var6-- > 0; var5[var6] = (char)(var2 | var1[var6 + var3] & 255)) {
;
}
}
this.value = var5;
}
/** @deprecated */
@Deprecated
public String(byte[] var1, int var2) {
this(var1, var2, 0, var1.length);
}
private static void checkBounds(byte[] var0, int var1, int var2) {
if (var2 < 0) {
throw new StringIndexOutOfBoundsException(var2);
} else if (var1 < 0) {
throw new StringIndexOutOfBoundsException(var1);
} else if (var1 > var0.length - var2) {
throw new StringIndexOutOfBoundsException(var1 + var2);
}
}
public String(byte[] var1, int var2, int var3, String var4) throws UnsupportedEncodingException {
this.hash32 = 0;
if (var4 == null) {
throw new NullPointerException("charsetName");
} else {
checkBounds(var1, var2, var3);
this.value = StringCoding.decode(var4, var1, var2, var3);
}
}
public String(byte[] var1, int var2, int var3, Charset var4) {
this.hash32 = 0;
if (var4 == null) {
throw new NullPointerException("charset");
} else {
checkBounds(var1, var2, var3);
this.value = StringCoding.decode(var4, var1, var2, var3);
}
}
public String(byte[] var1, String var2) throws UnsupportedEncodingException {
this(var1, 0, var1.length, (String)var2);
}
public String(byte[] var1, Charset var2) {
this(var1, 0, var1.length, (Charset)var2);
}
public String(byte[] var1, int var2, int var3) {
this.hash32 = 0;
checkBounds(var1, var2, var3);
this.value = StringCoding.decode(var1, var2, var3);
}
public String(byte[] var1) {
this((byte[])var1, 0, var1.length);
}
public String(StringBuffer var1) {
this.hash32 = 0;
synchronized(var1) {
this.value = Arrays.copyOf(var1.getValue(), var1.length());
}
}
public String(StringBuilder var1) {
this.hash32 = 0;
this.value = Arrays.copyOf(var1.getValue(), var1.length());
}
String(char[] var1, boolean var2) {
this.hash32 = 0;
this.value = var1;
}
/** @deprecated */
@Deprecated
String(int var1, int var2, char[] var3) {
this(var3, var1, var2);
}
length方法
通過獲取char[]的長度來獲取字串的長度
public int length() {
return this.value.length;
}
isEmpty方法
通過判斷char[]的長度是否為0來判斷是否為空
public boolean isEmpty() {
return this.value.length == 0;
}
charAt方法
通過char[]陣列下標獲取到對應位置的char字符
public char charAt(int var1) {
if (var1 >= 0 && var1 < this.value.length) {
return this.value[var1];
} else {
throw new StringIndexOutOfBoundsException(var1);
}
}
equals方法
首先比較記憶體地址,再判斷是否是String型別,然后再判斷長度,最后逐個比較其中的char,
public boolean equals(Object var1) {
//首先比較記憶體地址
if (this == var1) {
return true;
} else {
//判斷var1是否是String型別
if (var1 instanceof String) {
//如果是則強轉
String var2 = (String)var1;
//獲取當前String中char[]的長度
int var3 = this.value.length;
//如果傳入的var1和當前String中char[]的長度一樣
if (var3 == var2.value.length) {
char[] var4 = this.value;
char[] var5 = var2.value;
//將傳入的var1和當前字串中char[]中字符逐個比較,若有一個不一致則回傳false
for(int var6 = 0; var3-- != 0; ++var6) {
if (var4[var6] != var5[var6]) {
return false;
}
}
return true;
}
}
return false;
}
}
hashCode方法
這里的hash值計算有個特點,就是String內部快取了hash值,如果hash值不為0則直接回傳,不需要再次進行計算,因為String是被final修飾的,它不會被修改,所以沒有必要每次都重新計算hash值,
public int hashCode() {
//首先從String的成員變數hash獲取到hash值
int var1 = this.hash;
//如果hash值為0且當前String不為空
if (var1 == 0 && this.value.length > 0) {
//獲取到當前String的char[]
char[] var2 = this.value;
//逐個使用char回圈疊加計算hash值
for(int var3 = 0; var3 < this.value.length; ++var3) {
var1 = 31 * var1 + var2[var3];
}
//計算好后將hash值賦值給成員變數hash
this.hash = var1;
}
//最后回傳hash值
return var1;
}
compareTo方法
通過兩個字串的第一個不一樣的字符來比較大小并回傳結果,若兩個字串的字符都一樣則比較兩個字串的長度,
public int compareTo(String str) {
//分別獲取到當前String和傳入String的length
int thisLen = this.value.length;
int strLen = str.value.length;
//計算出兩個String最小的長度minLen
int minLen = Math.min(thisLen, strLen);
char[] thisValue = this.value;
char[] strValue = str.value;
//回圈找出兩個字串第一個不一樣的字符比較大小并回傳比較結果
for(int i = 0; i < minLen; ++i) {
char thisChar = thisValue[i];
char strChar = strValue[i];
if (thisChar != strChar) {
return thisChar - strChar;
}
}
//若兩個字串回圈比較的字符是一樣的,那么使用字串長度來比較大小
return thisLen - strLen;
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/222833.html
標籤:java
下一篇:shiro學習
