我们都知道,基本数据类型的比较我们一般用关系运算符 “==”以及”!=“。当然,这两个运算符也适用于所有对象,然而比较的结果却并不一定与预想的结果相符。
下面看一串代码:
public class Equals {
public static void main(String[] args) {
Integer a1 = new Integer(12);
Integer a2 = new Integer(12);
System.out.println(a1==a2);
System.out.println(a1!=a2);
}
}
关系操作符的运算结果是产生一个布尔值,初学java的读者也许会认为,第一个输出的是”true“,第二个输出的是”false“;然而结果却是下面:
大家可能感到惊奇,因为两个Integer a1和a2是一样的对象,那么它的内容也是相同的,可为什么输出的先是”false”,最后才是“true”,其实道理很简单,尽管两个对象的内容相同,然而它们对象的引用却是不同的,而“==”与“!=”比较的就是对象的引用。那么问题来了,我们改如何比较对象的内容呢?java类库中提供了一个equals()函数,就是用来比较对象的实际内容。
当我们把最后的输出代码改成:System.out.println(a1.equals(a2));它的运行结果则是:“true”,这就和我们预想的一样了。
然而事情并不是我们想象的那么简单,假如你创建了自己的类,就像下面一样:
class Value
{
int i;
}
public class Equals {
public static void main(String[] args) {
Value a1 = new Value();
Value a2 = new Value();
a1.i=a2.i=100;
System.out.println(a1.equals(a2));
}
}
我们看看运行结果:
结果又是false。这就令人奇怪了。不是说好的equals()比较的是对象的内容吗?我想大家都知道,Java中所有的类都是继承于Object这个基类的,而Object基类中定义了一个equals()方法,默认的行为是比较对象的引用,也可以说是比较对象的内存地址,但在一些类库中,它们本身自定义了一个equals()函数,比如String,Integer,Date中,自定义的equals()函数比较的是对象的内容,而不再是比较类的所生成对象的内存地址了。所以,当我们自己设计了一个类的时候,想要比较对象的内容,只要自己定义一个equals()函数,来覆盖掉从Object类继承的equals()函数。代码如下:
class Value
{
int i;
public boolean equals(Value a2)
{
if(this.i==a2.i)
return true;
else
return false;
}
}
public class Equals {
public static void main(String[] args) {
Value a1 = new Value();
Value a2 = new Value();
a1.i=a2.i=100;
System.out.println(a1.equals(a2));
}
}
运行结果如下:
很明显,现在自定义的equals()是比较对象的内容的,而且已经成功的覆盖掉从Object继承的equals()函数。所以以后再对象的比较中,要留意我们是要比较对象的内容呢,还是比较对象所存放的内存地址,这样就能避免我们出差错噢。