Java:assertEquals(String,String)可靠吗?

Div*_*ero 194 java string junit junit4

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

在相关的说明中,是否有人有一个页面或线程的链接,明确地解释了问题str1 == str2

jjn*_*guy 267

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

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

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

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

  • 如果两个字符串都为null,则IIRC assertEquals()成功.如果这不是你想要的,那么也调用assertNotNull(). (12认同)
  • 另外,如果你想测试==,你可以调用assertSame() (10认同)
  • 我不会说*总是*; 有时甚至对于字符串也需要引用相等. (6认同)

Lau*_*ves 30

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

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

比喻时间:想象每个String物体都是一张纸,上面写着一些东西.假设我有两张写有"Foo"的纸,另一张写着"Bar".如果我拿前两张纸并用==它来比较它们会返回,false因为它基本上是在问"这些是同一张纸吗?".它甚至不需要查看纸上写的内容.事实上,我给它两张纸(而不是相同的两张纸)意味着它将返回false.equals但是,如果我使用,该equals方法将读取两张纸,并看到他们说同样的事情("Foo"),所以它将返回true.

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


Car*_*ter 7

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);
    }
}
Run Code Online (Sandbox Code Playgroud)


Ken*_*Liu 7

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

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


Jac*_*eow 5

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

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

所以你很好。