Java等于方法解释如下代码

时间:2015-08-14 11:08:16

标签: java object equals

我一直在读一本名为Thinking in Java on 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


}

为什么这会给出错误?你的深度答案会得到很多人的期待。谢谢。

8 个答案:

答案 0 :(得分:1)

自定义类中equals的行为完全取决于您。如果覆盖它,则决定何时将类的两个对象视为彼此相等。如果你不覆盖它,你会得到Object类的默认实现,它会检查两个引用是否引用同一个对象(即检查你的例子中是v1==v2,这是假的)

答案 1 :(得分:1)

问题的根源:

您没有覆盖eqauals和hashCode,然后JVM将新的hashCode分配给您在Value类

的情况下创建的任何对象

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

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

1)重写equals方法并指定检查相等于实例变量i的值

2)覆盖Hashcode并使用实例变量i进行hashCode比较

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

public boolean equals(Object anObject)  {

if(this == anObject){

return true;

}         否则{

  // Do the calculation here to check the identity check 

} 

答案 2 :(得分:0)

因为你没有覆盖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

答案 3 :(得分:0)

Integer是有价值的类型。因此,与通过比较它们的值执行的Integer变量进行比较。在你的特定情况下,这是相同的。

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

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

答案 4 :(得分:0)

  

我知道这种平等的方法是比较参考。

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

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

答案 5 :(得分:0)

Integer的方法是equals(),它比较了值,而你的Value类并没有。它使Value类与equals比较"指针",并且它们不同。

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

public boolean equals(Object o){
   return (this.i == ((Value) o).i) ? true : false;
}

答案 6 :(得分:0)

  

那他们怎么平等?

整数是一个对象。另一方面, int 是一种简单类型。 整数的equals()方法比较int inside,因为它覆盖了Object equals()方法。 int具有相同的值。

  

为什么这会给出错误?

您的类并不会覆盖相同的方法,因此会比较参考,就像编写v1 == v2时一样。在这种情况下,它们是不同的对象,因此它是错误的。

答案 7 :(得分:0)

您对equals和==的理解是完全错误的,或与实际相反。

equals()方法也检查引用为==,除非你重写equals方法,否则它们之间没有区别。 ==检查参考相等性。为了更好地理解,请参阅Object类源代码。

 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

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