public final class String
implements java.io.Serializable, Comparable<String>, CharSequence {
// 內部結構存儲是char數據,用於存儲字符串的值
private final char value[];
// 緩存字符串的 hash code
private int hash; // Default to 0
private static final long serialVersionUID = -6849794470754667710L;
// 以String 爲參數的構造方法
public String(String original) {
this.value = original.value;
this.hash = original.hash;
}
// 以char[]數組爲參數的構造方法
public String(char value[]) {
this.value = Arrays.copyOf(value, value.length);
}
// 以StringBuffer爲參數的構造方法
public String(StringBuffer buffer) {
synchronized(buffer) {
this.value = Arrays.copyOf(buffer.getValue(), buffer.length());
}
}
// 以StringBuilder爲參數的構造方法
public String(StringBuilder builder) {
this.value = Arrays.copyOf(builder.getValue(), builder.length());
}
/**
* String 類型重寫了Object 中的equals()方法,equals()方法需要傳遞一個Object類型的參數
* 值,在比較時會先通過instanceof 判斷是否String類型,如果不是則會直接返回false
*/
public boolean equals(Object anObject) {
// 對象引用地址相同直接返回 true
if (this == anObject) {
return true;
}
// 判斷入參 anObject 類型是否爲String類型,若不是 則返回 false
if (anObject instanceof String) {
String anotherString = (String)anObject;
int n = value.length;
if (n == anotherString.value.length) {
// 把兩個字符串轉換成char[]數組進行對比
char v1[] = value;
char v2[] = anotherString.value;
int i = 0;
// 循環比較兩個字符串的每一個字符串
while (n-- != 0) {
// 若其中有一個字符串不相等返回false,否則繼續比較
if (v1[i] != v2[i])
return false;
i++;
}
// 當所有字符都相等的時候返回true
return true;
}
}
return false;
}
/**
*比較兩個字符串
* 若兩個字符串分別存儲1 和 2,返回的值爲 -1
* 若兩個字符串分別存儲1 和 1,返回的值爲 0
* 若兩個字符串分別存儲2 和 1,返回的值爲 1
*/
public int compareTo(String anotherString) {
int len1 = value.length;
int len2 = anotherString.value.length;
// 獲取兩個字符串長度最短的那個 int的值
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;
}
}
從源碼 可以看出 ,compareTo() 方法 和 equals() 方法都是用於比較連個字符串的,但他們有兩點不同:
1.equals() 可以接收一個Object類型的參數,而 compareTo() 只能接收一個String類型的參數
2.equals() 返回值爲boolean類型, 而compareTo()返回值則爲int類型
3. equals()方法返回true的時候表示兩個字符串相等,comparaTo() 返回0 的時候表示兩個字符串相等
拓展:
1. == 和equals() 的區別
== 對於基本數據類型來說,是用戶比較 "值" 是否相等
對於引用數據類型來說,是用戶比較引用地址是否相同的
通過查看 Object中的equals( ) 方法
public class Object {
public boolean equals(Object obj) {
return (this == obj);
}
}
equals()方法其實底層就是使用==, 而String重寫了equals() 方法把它修改成比較兩個字符串的值是否相等
String 在JVM中的存儲:
String str1 = new String("java");
String str2 = str1.intern();
String str3 = "java";
System.out.println(str1 == str2); // false
System.out.println(str2 == str3); // true
String常見的創建方式有兩種:
直接賦值的方式“Strings1="Java";”和“Strings2=newString("Java");”的方式,但兩者在JVM的存儲區域卻截然不同.
在JDK1.8中,變量str1會先去字符串常量池中找改字符串 "java",如果存在改字符串,則直接返回常量句柄,如果沒有此字符串,則會
現在常量池中創建此字符串,然後再返回常量句柄; 而變量str2是直接在堆上創建一個變量, 只有調用intern() 方法擦灰把此字符串保存到常量池中