比较两个对象时equals方法如何返回false:e1.equals(e2)

时间:2015-07-13 06:31:53

标签: java equals

class Emp { 
    public Emp(String s) {

    }
}

public class Testing { 
    public static void main(String[] args) { 
        Emp e1 = new Emp("hello"); 
        Emp e2 = new Emp("hello"); 
        System.out.println(e1 == e2); 
        System.out.println(e1.equals(e2));

        String s1 = new String("hello");
        String s2 = new String("hello");
        System.out.println(s1 == s2);
        System.out.println(s1.equals(s2));
    }

}

输出为:false false false true

4 个答案:

答案 0 :(得分:3)

如果不覆盖方法hashcodeequals,则默认equals方法如果位于同一内存位置,则返回true。由于e1e2是单独的对象,因此它们位于不同的内存位置,因此如果没有覆盖equalse1.equals(e2)将为false。

答案 1 :(得分:1)

为了使e1.equals(e2)返回true,Object' s equals的默认实现应返回true(需要e1==e2),或者您应该在equals类中覆盖Emp,以便在应用于e1e2个实例时返回true。

答案 2 :(得分:0)

“Emp”类从根“OBJECT”类继承equals()方法。

下面是Object类中的equals()方法代码:

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

如上所示,它检查内存位置地址是否相等。

第一种情况:

Emp e1 = new Emp("hello"); 
Emp e2 = new Emp("hello"); 
System.out.println(e1 == e2); 

在这里你要比较引用(内存位置),因为你在堆中创建了两个新对象,那里的memroy位置不同,因此它重新调整为“false”

第二种情况:

Emp e1 = new Emp("hello"); 
Emp e2 = new Emp("hello"); 
System.out.println(e1.equals(e2));

在这里,您将参与“Object”类中继承的equals()方法,该方法将检查这两个对象的引用(内存位置),从而重新调整为false。

第三种情况:

    String s1 = new String("hello");
    String s2 = new String("hello");
    System.out.println(s1 == s2);

在这种情况下,String类重写了equals()方法,它实际上检查了对象字段以进行比较,下面是String类中equals()方法的源代码:

public boolean equals(Object anObject) {
    if (this == anObject) {
        return true;
    }
    if (anObject instanceof String) {
        String anotherString = (String)anObject;
        int n = count;
        if (n == anotherString.count) {
            char v1[] = value;
           char v2[] = anotherString.value;
            int i = offset;
            int j = anotherString.offset;
            while (n-- != 0) {
                if (v1[i++] != v2[j++])
                    return false;
            }
            return true;
        }
    }
    return false;
}

这与第一种情况类似,在这里你要比较两个字符串对象的引用(内存位置),因为你在堆中创建了两个新对象,那里的memroy位置不同,因此它重新调整为“false”

第四种情况:

    String s1 = new String("hello");
    String s2 = new String("hello");
    System.out.println(s1.equals(s2));

这里是从字符串类(上面粘贴的代码)调用重写的equals()方法。如果你看到逻辑它首先实际检查两个引用是否引用相同的内存位置,如果它返回true,否则它将实际检查由charcter数组支持的两个字符串对象的内容,它比较每个这些两个字符串对象的coressponding字符的字符,因为两个对象具有相同的内容“hello”,它返回true。

如上所述,请通过equals()和hashcode()合同。

答案 3 :(得分:0)

        System.out.println(e1 == e2);  <-- A
        System.out.println(e1.equals(e2)); <-- B
        System.out.println(s1 == s2); <-- C
        System.out.println(s1.equals(s2)); <-- D
  1. 表达式A =&gt;返回假。这很明显,因为这个表达式正在比较两个不同的对象
  2. 表达式B =&gt;返回假。每个类隐式扩展Object类。因此,equals方法的实现使用Object类中定义的与表达式A相同的方法
  3. 表达式C =&gt;返回假。原因与表达式A比较两个不同的对象
  4. 相同
  5. 表达式D =&gt;回归真实。因为String类有自己的equals函数实现,它检查字符串的值。