等于Java 7中2个对象的比较

时间:2013-03-12 15:58:13

标签: java object equals

public class ObjectEqualsComparison {
      public static void main(String[] args) {      
           Object ob1 = new Object();  // address location 0×1234 
           Object ob2 = new Object();  // address location 0×2345 

           System.out.println(ob1 == ob2); // prints false correct
           System.out.println(ob1.equals(ob2)); //prints false which is incorrect//it should be true.

           //ob1 == ob2 gives false which is correct since you are comparing address/references .
           //ob1.equals(ob2) is also giving false.can you tell me why since we are comparing contents       
        }
}

编辑::我的问题是我需要覆盖equals()方法。所以equals()覆盖方法应该如何。请帮助

2 个答案:

答案 0 :(得分:1)

System.out.println(ob1.equals(ob2));的输出是正确的,因为您正在比较类型object的实例。如果您要比较覆盖equals的类型的实例,那么这将是一个不同的故事!

例如,如果你有:

class SomeType{

    private Object comparisonField;

    public SomeType(Object comparisonValue){
        this.comparisonField = comparisonValue;
    }

    @overrides
    public int getHashCode(Object other){
        if(this.comparisonField == null)
            return super.getHashCode();

        return this.comparisonField.getHashCode();
    }

    @overrides
    public boolean equals(Object other){
        if(comparisonField == null || other == null)
           return super.equals(other);

        return comparisonField.equals(((SomeType)other).comparisonField);
    }
}

比较时:

SomeType inst1 = new SomeType("SAME VALUE");
SomeType inst2 = new SomeType("SAME VALUE");

bool areEqual = inst1.equals(inst2);  // calls the overriden equals method on SomeType
                                      //   which would return TRUE 

// but if you use object:

Object obj1 = new Object();
Object obj2 = new Object();

bool areEqual = obj1.equals(obj2);    // will call equals on Object;
                                      //   and always return false;

答案 1 :(得分:1)

只有当2个对象是同一个实例,即内存中的同一个对象时,Object中找到的equals()的默认实现才会返回true。每次创建2个单独的Object实例时,它们都不会在内存中引用相同的对象,这就是它返回false的原因。

正如Miky指出的那样,您可以通过覆盖类中的equals()来修改该默认行为以提供自定义等效语义。

但是,Miky在将您的类(例如他的示例中的SomeType实例)转换为Object时会改变equals()的结果。

boolean areEqual = obj1.equals(obj2);

仍将调用SomeType定义的重写的equals()方法,而不管它是否通常被引用为其超类型Object。这就是多态性的力量。

因此,要回答原始问题,您必须创建自己的类,并在该类中使用实现来执行覆盖等于(),该实现执行对您的类有意义的等效检查。例如,如果您有一个Customer类,并且客户是通过其电子邮件地址唯一定义的,那么在Customer.equals()中,您将比较电子邮件地址,如果它们相同则返回true。

请记住,equals()的签名接受Object参数。正确构造的equals实现将检查参数是否为null以及它是否是相同类型的实例。还要注意,当你重写equals()时,你必须覆盖hashCode()。

有很多关于重写equals()和hashCode()的信息,我建议你研究一下。一个好的起点始终是“Effective Java”一书。