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() 方法擦灰把此字符串保存到常量池中