繁体   English   中英

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

[英]How equals method returns false when comparing two objects: e1.equals(e2)

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));
    }

}

输出IS: false false false true

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

为了使e1.equals(e2)返回true, Objectequals的默认实现应返回true(这要求e1==e2 ),或者您应以返回的方式重写Emp类中的equals应用于e1e2实例时为true。

“ 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); 

在这里,您正在比较reference(内存位置),因为您在堆中创建了两个新对象,因此内存位置不同,因此将其重新调整为“ 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;
}

这与第一种情况类似,在这里您将比较两个字符串对象的reference(内存位置),因为您在堆中创建了两个新对象,因此内存位置不同,因此将其调整为“ false”

第四种情况:

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

在这里,您要从字符串类(上面粘贴的代码)中调用重写的equals()方法。 如果您看到逻辑,它首先实际检查两个引用是否指向相同的内存位置(如果相同),则返回true,否则它将实际检查由charcter数组支持的两个字符串对象的内容,并将每个对象进行比较这些拖曳字符串对象的核心字符对应的字符,因为两个对象的内容都相同“ hello”,所以返回true。

正如Ken前面提到的,请通过equals()和hashcode()契约。

        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 =>返回false。 这是很明显的,因为此表达式正在比较两个不同的对象
  2. 表达式B =>返回false。 每个类都隐式扩展Object类。 因此,equals方法的实现是使用Object类中定义的方法,该方法与表达式A相同。
  3. 表达式C =>返回false。 原因与表达式A比较两个不同的对象相同
  4. 表达式D =>返回true。 因为String类具有自己的equals函数实现,该函数检查字符串的值。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM