211

我知道==比较两个时会有一些问题Strings。这似乎String.equals()是一个更好的方法。好吧,我正在做 JUnit 测试,我倾向于使用assertEquals(str1, str2). 这是断言两个字符串包含相同内容的可靠方法吗?我会使用assertTrue(str1.equals(str2)),但是您不会从失败时看到预期值和实际值的好处。

在相关说明中,是否有人有指向页面或线程的链接,可以清楚地解释问题str1 == str2

4

7 回答 7

291

在 Java 中进行比较时应始终使用。.equals()Strings

JUnit 调用.equals()方法来确定方法中的相等性assertEquals(Object o1, Object o2)

因此,您绝对可以安全使用assertEquals(string1, string2). (因为Strings 是Objects)

==这是一个关于和之间的一些差异的 Stackoverflow 问题的链接.equals()

于 2009-07-29T17:51:30.317 回答
33

assertEquals使用equals方法进行比较。有一个不同的断言,assertSame,它使用==运算符。

要理解为什么==不应该与字符串一起使用,您需要了解==它的作用:它进行身份检查。也就是说,a == b检查是否ab引用同一个对象。它是语言中内置的,它的行为不能被不同的类改变。equals另一方面,该方法可以被类覆盖。虽然它的默认行为(在Object类中)是使用运算符进行身份检查==,但包括 在内的许多类String都覆盖它以进行“等效”检查。在 的情况下String,而不是检查是否ab引用同一个对象,a.equals(b)检查它们引用的对象是否都是包含完全相同字符的字符串。

类比时间:想象每个String物体都是一张纸,上面写着一些东西。假设我有两张纸,上面写着“Foo”,另一张纸上写着“Bar”。如果我拿前两张纸==来比较它们,它会返回false,因为它本质上是在问“这些是同一张纸吗?”。它甚至不需要看纸上写了什么。我给它两张纸(而不是两次)的事实意味着它会返回false。但是,如果我使用equals,该equals方法将读取两张纸并看到它们说的是同一件事(“Foo”),因此它将返回true

与字符串混淆的一点是,Java 有一个“实习”字符串的概念,并且(有效地)自动在代码中的任何字符串文字上执行。这意味着如果您的代码中有两个等价的字符串文字(即使它们在不同的类中),它们实际上都会引用同一个String对象。这使得==操作员返回true的频率比预期的要高。

于 2009-07-29T18:15:48.620 回答
8

简而言之 - 您可以有两个 String 对象,它们包含相同的字符但是不同的对象(在不同的内存位置)。== 运算符检查两个引用是否指向同一个对象(内存位置),但 equals() 方法检查字符是否相同。

通常你感兴趣的是检查两个字符串是否包含相同的字符,而不是它们是否指向相同的内存位置。

于 2009-07-29T18:15:06.187 回答
6
public class StringEqualityTest extends TestCase {
    public void testEquality() throws Exception {
        String a = "abcde";
        String b = new String(a);
        assertTrue(a.equals(b));
        assertFalse(a == b);
        assertEquals(a, b);
    }
}
于 2009-07-29T17:54:28.233 回答
3

是的,它一直用于测试。测试框架很可能使用 .equals() 进行此类比较。

下面是解释“字符串相等错误”的链接。本质上,Java 中的字符串是对象,当您比较对象是否相等时,通常会根据内存地址而不是内容进行比较。因此,两个字符串不会占用相同的地址,即使它们的内容相同,所以它们不会正确匹配,即使它们在打印时看起来相同。

http://blog.enrii.com/2006/03/15/java-string-equality-common-mistake/

于 2009-07-29T17:48:48.527 回答
3

JUnitassertEquals(obj1, obj2)确实调用了obj1.equals(obj2).

还有assertSame(obj1, obj2)which 确实obj1 == obj2(即验证obj1obj2引用同一个实例),这是您要避免的。

所以你没事。

于 2009-07-29T18:06:12.060 回答
0

==操作员检查两个Objects是否完全相同Object。”

http://leepoint.net/notes-java/data/strings/12stringcomparison.html

String在java中是一个Object,所以它属于那种比较规则。

于 2009-07-29T17:51:44.653 回答