测试对象的等价性——"=="和"equals"

关系运算符== 和 !=也适用于对象。看下面这个例子:

public static void main(String[] args) {
        Integer i = new Integer(1);
        Integer j = new Integer(1);
        System.out.println(i==j); //输出false
        System.out.println(i!=j); //输出true
}

i的值明明等于j的值,为什么会输出flase?因为 ==和!=比较的是引用所指的对象是否相同。i == j表达的意思是:i这个引用指向的对象和j这个引用指向的对象是相同的吗?i这个引用指向Integer的一个对象,j这个引用指向Integer的另一个对象。所以会输出false。
下面我们将代码修改,加以验证。

public static void main(String[] args) {
        Integer i = new Integer(3);
        Integer j = new Integer(1);
        i = j;      //我们让其发生"别名现象",使i这个引用和j这个引用都指向j引用所指的对象。这样它们所指的对象就相同了
        System.out.println(i==j);  //输出true
}

那么怎样才能比较两个对象的内容是否相同呢?这时必须使用所有对象都适用的特殊方法equals()。它是Object类中定义的方法,因为Java中所有的类都继承于Object,因此所有的类都有这个方法。

public static void main(String[] args) {
        Integer i = new Integer(1);
        Integer j = new Integer(1);
        System.out.println(i.equals(j)); //输出true
}

然而事情并不总是这么简单,假设你创建了自己的类:

class Value{
    int i;
}

public class Sum {
    public static void main(String[] args) {
      Value value1 = new Value();
      Value value2 = new Value();
      value1.i = value2.i = 100;
      System.out.println(value1.equals(value2));//输出false
    }
}

这又是怎么回事呢?
上面已经提到了所有类都继承于Object,我们新建的Value类也不例外,尽管表面上它没有定义任何方法,实际上它从Object哪里继承了许多方法,而equals()就是其一。
至于结果为什么会是false,这和Object类中equals()方法的实现有关,我们来看看源码:

  public boolean equals(Object obj) {
        return this == obj;
    }

结果显而易见,equals()默认行为比较的是引用是否指向同一个对象。
那么问题又来了?
为什么Integer的对象调用equals()就能得出正确答案呢?这是因为Integer类重写了equals()方法。所以要想得到我们希望的行为,除非在自己的新类中重写equals()方法。

posted @ 2020-09-07 21:36  xxgbl  阅读(208)  评论(0)    收藏  举报