equals方法如何在java中工作

时间:2015-03-15 09:01:07

标签: java

我问的是非常基本的问题,但是真的很困惑equals方法在java中是如何工作的。让我举一个例子,我在类级别声明类型为String的三个变量。

String a = "abc";
String b = "abc";
String c = new String("abc");

然后根据java拇指规则编写一个比较它们的方法。

public void compare(){
        System.out.println("a.equals(c) :" + a.equals(c));
        System.out.println("a == b :" + (a == b));
        System.out.println("a ==  c :" + (a == c));
    }

现在,当我运行该程序时,它给了我以下输出。

a.equals(c) :true
a == b :true
a ==  c :false

现在我很困惑,因为我知道写成文字的字符串总是被创建到StringPool中。这意味着变量a和b将被创建为StringPool,并且根据stringPool,将只有一个实例,变量a和b将指向此变量。变量c将被创建到堆内存中。当我比较a.equals(c)时,它给了我真实的可能性,因为equals的默认实现总是比较内存分配而不是内容。它应该返回false。

我也在为整数做同样的事情,比如

Integer m  = 1;
    Integer n  = 1;
    Integer o  = new Integer(1);

public void compareInt(){
        System.out.println("m.equals(o) :" + m.equals(o));
        System.out.println("m == n :" + (m == n));
        System.out.println("m ==  o :" + (m == o));
    }

out is

m.equals(o) :true
m == n :true
m ==  o :false

现在再次感到困惑。所有三个变量都将被创建到头部内存中,因为对于整数,现在有IntegerPool。然后m == n如何给出真实,因为再次==运算符比较引用而不是内容,并且根据我的理解参考是不同的。在这种情况下,equals方法的行为与String中的相同。

可以帮助了解正在发生的事情。

1 个答案:

答案 0 :(得分:6)

字符串和整数覆盖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;
}

哦,整数确实有-128到127之间的值的缓存,这解释了为什么m==n返回true。