最近感觉对Java总有种似懂非懂的感觉,刚好前不久同学经常问我equals的问题,于是找到equals的源码彻底的弄懂它。
在我们学习Java的时候,都经常在String类中调用该方法,以此来比较两个String类的内容是否相等,初学Java的时候很多人==与equals分不清,究其原因是因为Java的继承机制,==始终是比较的两者的地址,而equals方法查Java源码可得,最初始的是继承于Object的equals类,查看源码可得:
public boolean equals(Object obj) {
return (this == obj);
}
从代码可知,Object类的equals方法是比较的地址,所以最初的equals方法和==的作用是一致的。而String类覆写的equals方法为:
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;
}
在String的equals源码中,先比较的是两个String类的地址,后比较的是两个String类中的内容,在比较内容的时候先比较的是String的长度,后用两个Char数组比较字符是否相等。所以很容易得出下面这段代码的值:
package equals;
import java.util.Scanner;
public class Test {
public static void main(String args[]){
String string1="0";
String string2="0";
String string3=null;
Scanner scan=new Scanner(System.in);
string3=scan.nextLine();
System.out.println(string1=="0");
System.out.println(string1==string2);
System.out.println(string1==string3);
System.out.println(string1.equals(string3));
//System.out.println(string3.equals("0"));
String[] a={"1","2","3"};
String[] b={"1","2","3"};
System.out.println(a==b);
System.out.println(a.equals(b));
}
}
在这里顺带提示一下,String类是常量,存储在常量池里,如果初始化了一个String类,再用相同的字符串去初始化另一个String类,则它们两者共用一个地址,从某种意义上说,它们是完全相等的。
而建立两个内容相同的String类数组,调用equals方法为什么显示的结果是false呢?这里值得注意一下,这里的引用类型变了,从String类变成了String[],而String[]的equals查看源码可知,它继承Object类后没有对equals覆写后没有进行改写,依旧是Object类的方法。两者地址不同,自然结果是false。