最近看了一本关于Java的基础书,由于我的Java基础已经学过去好久。想着巩固一下基础,把以前不太清楚的东西。搞的明白些。
于是就遇到了这个问题,书上大概说是,“==”可以用于比较基本数据类型,还可以判别两个引用对象是否指向同一个对象。而equals方法则是判断两个对象是否在意义上相等!!!????“意义?”什么鬼,难道是方法和变量都相同!!?
尝试了new了两个相同的对象,发现无论是用“==”还是equals都是false,突然恍然大悟,这就是两个不同的对象啊,怎么能相等?于是我还编写了一大堆的比较方法,就是使用“==”和“equals”方法。
@Test
public void test4() {
Dog dog = new Dog();
Dog dog2 = dog;
dog2.setName("dog");
Dog dog1 = new Dog();
Dog dog3 = new Dog();
//使用“==”判断
//第一个判断
ifDog1(dog, dog2);//true
System.out.println("==========");
//第二个判断
ifDog1(dog,dog1);//false
System.out.println("==========");
//第三个判断
ifDog1(dog1,dog2);//false
System.out.println("==========");
//第四个判断
ifDog1(dog1,dog3);//false
System.out.println("==========");
//使用equals
//第五个判断
ifDog2(dog, dog2);//true
System.out.println("==========");
//第六个判断
ifDog2(dog,dog1);//false
System.out.println("==========");
//第七个判断
ifDog2(dog1,dog2);//false
System.out.println("==========");
//第八个判断
ifDog2(dog1,dog3);//false
}
这才后知后觉发现我咋这么蠢,是要new过的,肯定就是两个不同的对象。从比较结果看,发现“==”和“equals”没有区别,但是这两个肯定有区别呀,要不然我老是听到,有人问这两个的区别是啥。这时还给我一个通过发了一下,我同学很快就判断出来,并点破我。说只要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;
}
发现天机,这里就是使用了“==”效果一样。只不过下面多了其他一些东西。当时没有仔细看多的是什么。就是有种参破天机的感觉。但是我还是没有发现有什么不同。于是我百度一下。那个人写的啥我忘了,但是那个里面用的例子就是:new了两个字符串,字符串的值一样,进行比较。竟然使用“==”的为false,使用equals的为true。当时感觉参破的天机又自己合上了。哎,有点不解。代码如下:
String a = new String("c");
String b = new String("c");
System.out.println(a==b); //false
System.out.println(a.equals(b)); //true
突然我有想起了,刚才那个我同学说的重写的equals方法。点开equals源码,这回才注意到下面的代码,返回true有两个条件,一个条件是两个对象“==”的时候,还有就是,将传递进来的对象,直接转换为String类型,然后进行字符比较。全相同也可以true。这里又顿悟了。哈哈。
这时想起了我同学,我再次去把上面这个判断发过去,看看他是否理的清。给他分享下。这回他错了。我说是重写了,这个equals方法,就像他刚说的一样。但是他又提出了新的观点,他说是重写了toString。我当时想都没想说,不可能吧,toString都没调用。但是最后发现toString时调用的。
但是最后我又想。好像其实也不是真的不可能啊,打印出来的都是相同的字符。只比较相同的字符的话不是就是true了!!又有点迷惑了。
想来想去还是要究其根本,看这个toString是在什么是后执行的,打上断点后,发现初始化对象时,new 一个String对象。发现里面的方法toString是执行的。但是这里的返回值是一个this。
public String toString() {
return this;
}
并没有做任何的处理。
说明我上面的推测是正确的。
最后发现是在调用println时,toString方法被调用。点开源码,我并没有找到哪里调用了toString但是我打上断点后,确实调用了toString方法。所以比较时,返回的是一个Boolean类型,基本数据类型,应该也不会调用toString,算调用也没有啥关系吧。这时时println的行为,和两个对象没有关系了。
总结:
1,“==”和“equals”本质上时没有区别,equals也是‘==’。
2,但是重写equals可以手动添加其他效果,典型例子就是String类型和Integer类型。
3,toString并不会干扰“==”或者“equals”的判断结果。
以上都是个人见解,如有哪里不正确的地方,请各位及时指正。因为本人也菜,请见谅。