Java中String类型的默认等于实现是如何工作的?

5
我们都知道如果我们创建两个String对象并使用==比较它们,它将返回false,如果我们使用equals方法,它将返回true。但默认情况下equals方法只实现了==运算符,那么它如何返回true?它应该返回==返回的任何内容吗?

equals方法在String类中被重写了。这就是为什么。 - AmitG
5个回答

9

默认情况下,Object类的equals方法实现了==。但是你可以在自己的类中重写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;
      }

所以,这就是以下代码的原因:
String s1 = new String("java");
String s2 = new String("java");

s1==s2 返回 false,因为这两个变量所引用的是堆内存中不同的对象。而s1.equals(s2) 返回true,因为现在调用的是String类内定义的equals方法,该方法会根据String字符串的内容进行比较。


1
默认情况下,equals 方法不会为 String 类实现 ==。他的问题是,即使 equals 实现了 ==,它们两者的行为仍然不同! - Amar
@Amar:在你给别人的答案投反对票之前,请重新阅读问题并思考成熟。OP问的是,由于equals方法默认检查==,那么两个内容相同但不同的Stringequals方法如何返回true?这就是我在我的答案中解释原因的地方。也请重新阅读我的答案。 - Vishal K
也许吧!我从这个问题中理解到他实际上看到了 String 的实现,并且对方法中的初始 == 检查感到困惑。如果我的理解是错误的,我一定会撤回我的踩票。顺便说一句,在这里不需要个人攻击并评论我的成熟度。冷静点。 - Amar
@Amar:如果 OP 查看了 String 类中的 equals 方法源代码,我相信他就不会提出这个问题了。因为在 String 类的 equals 方法中,当 == 失败时,还会进行其他检查... 这一点肯定会被 OP 注意到的。 - Vishal K
我尝试编辑答案并将s1==s1更改为s1==s2,但这并不足以使编辑立即生效。我认为纠正这个笔误可以改善答案。 - gcbound
显示剩余2条评论

1

String类中的equals方法被重写,它试图检查两个字符串中的所有字符是否相等。如果相等,则返回true。因此,String类中的equals方法的行为与普通对象类的实现不同。


0

.equals() 方法用于检查字符串是否相同,即是否具有相同的字符。而 == 只检查指针是否指向相同的对象。你可以拥有不同的对象,但它们具有相同的字符,这就是为什么应该使用 .equals() 来进行比较。


0

equals方法最初是Object类的一个方法。在Java中,每个类默认都会扩展Object类。现在,equals方法被重写为String类,以使其与==有所不同。

它的javadoc解释得非常完美:

将此字符串与指定对象进行比较。当且仅当参数不为null并且是表示与此对象相同字符序列的String对象时,结果为true。

它的实现如下:

@override
public boolean equals(Object anObject) {
// This check is just for the case when exact same String object is passed
if (this == anObject) {
    return true;
}
// After this only real implementation of equals start which you might be looking for
// For other cases checks start from here
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;
}

0
Java中的String类覆盖了Object类的equals方法,使其比较两个字符串的内容而不是比较引用(Object类的默认实现)。
请参见下面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;
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接