最近遇到了许多关于equals(Object o)方法的探,个人觉得有必要在这里总结一下,以备哪时忘了,好翻下。
首先我们来说下Object.equals(Object o),提供的初忠是为了比较两个对象是不是同一个引用。而不是比较是不是同样的值。例如如下代码:
A a = new A();
A a2 = new A();
a.equals(a2);
这里的equals方法将返回一个false;因为这两个对象不是同一个对象,所以指向的是不同的引用。若改为:
A a = new A();
A a2 = a;
a.equals(a2);
那么这里则返回一个true。因为这里两个对象指向了同一个引用。这里需要注意的一个地方,就是这里的equals方法和==比较是同样的,都是比较两上对象是否是是同样的引用。
String 的equals方法,是重写了Object的equals方法,比较的是两个字符串对象,是不是相同的值。而==是比较两字符串的引用是否相等。来看个实例:
String a = new String("aaa");
String a1 = new String(:"aaa");
在这里,a==a1为false,a.equals(a1)为true,这个和上面是印证的。equals比较的是两个对象中是否存在同样的值,而不是同样的引用。所以equals返回为true,==则返回false.
接下来,我们改动一下代码为如下:
String a = "aaa";
String a1 = "aaa";
现在再去比较,发现不一样了呢?这是为什么呢?其实这个是因这里定义的String对象,是用了两个同样的引用了,当你定义前一个a对象时,JAVA就在常量池中创建了一个内容为“aaa”的常量,然后创a1时,则先查找常量池中有没有“aaa”的常量,如果有,则直接引用,没有再创建。这种方式创建的两个对象,equals和==都返回的是TRUE.这下应该明白了吧?那再改下:
String a = "aaa";
String a1 = new String("aaa");
有了上面的解释,这里也就不用多解释了吧?
那么equals方法的规则是怎么样的呢?有怎么样的约定?
在JAVA中,equals方法的约定有四个:
一、自反性(reflexiive).对于任何非null的引用值x,x.equals(x)必须反回为true。
二、对称性(symmetric).对于任何非null的引用值x和y,当且仅当y.equals(x)为true时,x.equals(y)也必须返回为true。
三、传递性(transitive).对于任何非null的引用值x、y和z,如果x.equals(y)为true,并且y.equals(z)为true时,则x.equals(z)也必须返回true。
四、一致性(consistent)。对于非null的引用值x和y,只要equals的比较操作在对象中所有的信息没有被 修改,多次调用x.equals(y)就会一致返回true或返回false.
另外需要注意的是:对于任何非空对象x,x.equals(null)必须返回false。
如果你一旦重写了equals方法,那么一定要根据四个约定对你的方法进行检测,确保你的equals正确。如果你违反了某条约定,那么当有其它对象调用你的对象时,你将不知道你的对象会产生什么样的行为。
这里多讲一下,如果你重写了equals方法,那么,也应该重写hashCode方法。这里不作讨论。