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

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

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

本文参考文章:https://blog.csdn.net/Chen_dSir/article/details/51887849

总结:这两个操作符比较的是对象的引用,equals()在这个java类库中比较的是内容;但是默认情况下equals()也是比较对象的引用,但是java中好多类库都实现了比较内容;

猜你喜欢

转载自blog.csdn.net/zdb292034/article/details/82080117
今日推荐