如何测试java中对象的等价性

来源:互联网 发布:网络诈骗手段及防范 编辑:程序博客网 时间:2024/06/06 09:51

我们都知道,基本数据类型的比较我们一般用关系运算符 “==”以及”!=“。当然,这两个运算符也适用于所有对象,然而比较的结果却并不一定与预想的结果相符。
下面看一串代码:

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()函数。所以以后再对象的比较中,要留意我们是要比较对象的内容呢,还是比较对象所存放的内存地址,这样就能避免我们出差错噢。

0 0