Java equal方法解释如下代码



我一直在读一本名为《在Java上用Java思考》的书(我来自C背景(。我遇到了以下两组代码

  public class EqualsMethod {
      public static void main(String[] args) {
        Integer n1 = new Integer(47);
        Integer n2 = new Integer(47);
        System.out.println(n1.equals(n2));
      }
    } 
//Output: true

我理解这种平等的方法是比较参考。但n1和n2是驻留在堆中两个不同"气泡"中的两个对象。那么为什么他们是平等的呢?

另一个示例代码是

class Value {
  int i;
}
    public class EqualsMethod2 {
      public static void main(String[] args) {
        Value v1 = new Value();
        Value v2 = new Value();
        v1.i = v2.i = 100;
        System.out.println(v1.equals(v2));
      }
    } /* Output:false

}

为什么这是假的?你的深入回答将备受期待。非常感谢。

equals在自定义类中的行为完全取决于您。如果覆盖它,则决定类中的两个对象何时被视为相等。如果您不重写它,您将获得Object类的默认实现,它检查两个引用是否引用了同一个对象(即,在您的示例中检查v1==v2是否为false(。

问题根源:

您没有覆盖eqauals和hashCode,然后JVM为您在Value类的情况下创建的任何对象分配一个新的hashCode

=====================

解决方案:您需要定义衡量价值对象身份的标准,即执行以下

1( 重写equals方法,并指定在实例变量i 的值上检查equals

2( 重写哈希代码并使用实例变量i进行哈希代码比较

==用于对象类中的equals方法,以避免在两个引用指向同一对象时进行不必要的计算,如果不进行计算和比较

公共布尔值等于(Object和Object({

如果(this==anObject({

返回true;

}其他{

  // Do the calculation here to check the identity check 
} 

我理解这种平等的方法是比较参考。

错了。在Object类中,此方法包含引用比较,但Integer有自己的实现,它覆盖了Object提供的实现。

它比较两个整数的值,而不是它们的引用。

Integer是有价值的类型。因此,与Integer变量相比,通过比较它们的值来执行。在你的特殊情况下是平等的。

比较通过比较不相等的引用执行的两个对象(引用类型(。

您可以通过在类中重载equals()方法来编写自己的比较逻辑。

Integer有比较值的方法equals((,而value类没有。它使具有equals的Value类比较"指针",它们是不同的。

如果重写类Value中的equals方法,比较类中的属性i,则它将返回true。例如

所有Wrapper类中的
public boolean equals(Object o){
   return (this.i == ((Value) o).i) ? true : false;
}

Equals方法在java中默认被覆盖。这就是为什么第一个片段有效。对于您自己的类,您必须提供equals方法的实现。

默认情况下,Java中的equal方法会检查两个Object引用是否相同。您可以@覆盖方法,并执行您想要的操作。所以得到False是正常的,因为这两个Object是不同的。

那么为什么他们是平等的呢?

Integer是一个Object。另一方面,int是一个简单的类型。Integer的equals((方法比较内部的int,因为它覆盖了Object equals(((方法。int的值相同。

为什么这是假的?

您的Value类不会覆盖equal的方法,因此会比较引用,就像您编写v1==v2时一样。在这种情况下,它们是不同的对象,所以这是错误的。

因为您没有覆盖equals方法。如果您不覆盖它,那么它将检查引用是否相等,并相应地返回。

可以参考Integer类中定义的equals()方法。

System.out.println(n1.equals(n2)) // this prints true because it refers to Integer equals method.

类似地,您将不得不为您的Value类重写它。

class Value {
    int i;
    @Override
    public boolean equals(Object obj) {
        boolean returnValue = false;
        if (obj != null && obj instanceof Value) {
            Value valObj = (Value) obj;
            if (this.i == valObj.i) {
                returnValue = true;
            }
        }
        return returnValue;
    }
}

现在System.out.println(v1.equals(v2));打印true

嗨,你对等号和==的理解是完全错误的,或者与实际情况相反。

equals((方法也像==一样检查引用,除非重写equals方法,否则两者之间没有区别。==检查引用是否相等。要更好地理解,请参阅对象类源代码。

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

为什么它在你的情况下有效?是因为Integer类重写了其中的equals方法。

public boolean equals(Object obj) {
if (obj instanceof Integer) {
    return value == ((Integer)obj).intValue();
}
return false;
n
}

现在,当您使用自定义类来检查相等性时,它所做的基本上是调用。

v1==v2

它怎么能给你真实的?它们在堆中都有不同的内存位置。如果仍然不清楚,请在代码中设置断点,并在调试模式下运行它。

最新更新