- 下面我们先由一个简单的例子引出equals的String底层代码:
package equals;
public class Equals {
public static void main(String[] args) {
String name1="Tom";
String name2="Tom";
System.out.println(name1==name2);
System.out.println(name1.equals(name2));
/* public boolean equals(Object anObject) {//name2传入equals方法——>anObject指向name2对象——>name2为上转型对象
if (this == anObject) {//因为name1与name2都是采用直接赋值的方式创建的String类型的对象——>==true
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;
}*/
}
}
- 我们再来对上面代码做一下稍许改变
package equals;
public class Equals {
public static void main(String[] args) {
String name1="Tom";
String name2=new String("Tom");
System.out.println(name1==name2);
System.out.println(name1.equals(name2));
}
}
思考:此时的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;
}*/
首先,当执行第一个if语句时,因为name1与name2的地址不同,所以此处为false,此时代码执行来到了下一个if的循环语句,又因为anObject参数指向name2对象——>name2为String类型对象——>anObject instanceof String为true。因为value是全局变量——>实质是this.value.length——>name1调用equals ——>this即为name1——this.value.length就是name1的字符有多少个
if (n == anotherString.value.length) //anotherString——>指向name2,即anotherString.value.length代表name2有多少个字符。若name1和name2两个字符串相同,则长度一定相同,所以n == anotherString.value.length非常重要,是判断两个字符串是否完全相同的首要标准。
接下来 char v1[] = value;//由name1字符组成的数组;char v2[] = anotherString.value;//由name2字符组成的数组;在while循环中,再逐个字符进行比对,只要有一个比对失败,则两个字符串一定不相同。
- 这时如果创建的对象是属于不同类的时候
package equals;
import junit.framework.Test;
public class Equals {
public static void main(String[] args) {
String name1="Tom";
Test test=new Test();
System.out.println(name1==test);//因为javac在编译时已经知道连类型都不相同,所以编译出错
System.out.println(name1.equals(test));
}
}
思考:此时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;
}
首先test传入equals方法——>anObject指向test对象——>test为上转型对象,又因为name1与test地址不同——>fasle,即第一个if语句判断结果为false,这时候再来判断第二个if语句,因为anObject参数指向test对象——>test为Test类型对象,不是String类——>anObject instanceof String 该句判断结果为false。