Java 的 assertEquals 方法可靠吗?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1201927/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 00:52:06  来源:igfitidea点击:

Is Java's assertEquals method reliable?

javastringjunitjunit4

提问by DivideByHero

I know that ==has some issues when comparing two Strings. It seems that String.equals()is a better approach. Well, I'm doing JUnit testing and my inclination is to use assertEquals(str1, str2). Is this a reliable way to assert two Strings contain the same content? I would use assertTrue(str1.equals(str2)), but then you don't get the benefit of seeing what the expected and actual values are on failure.

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

On a related note, does anyone have a link to a page or thread that plainly explains the problems with str1 == str2?

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

采纳答案by jjnguy

You should alwaysuse .equals()when comparing Stringsin Java.

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

JUnit calls the .equals()method to determine equality in the method assertEquals(Object o1, Object o2).

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

So, you are definitely safe using assertEquals(string1, string2). (Because Strings are Objects)

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

Here is a link to a great Stackoverflow questionregarding some of the differences between ==and .equals().

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

回答by Soviut

Yes, it is used all the time for testing. It is very likely that the testing framework uses .equals() for comparisons such as these.

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

Below is a link explaining the "string equality mistake". Essentially, strings in Java are objects, and when you compare object equality, typically they are compared based on memory address, and not by content. Because of this, two strings won't occupy the same address, even if their content is identical, so they won't match correctly, even though they look the same when printed.

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

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

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

回答by Zachery Delafosse

"The ==operator checks to see if two Objectsare exactly the same Object."

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

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

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

Stringis an Objectin java, so it falls into that category of comparison rules.

StringObject在java中是一个,所以它属于比较规则的类别。

回答by Carl Manaster

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);
    }
}

回答by Hyman Leow

The JUnit assertEquals(obj1, obj2)does indeed call obj1.equals(obj2).

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

There's also assertSame(obj1, obj2)which does obj1 == obj2(i.e., verifies that obj1and obj2are referencing the sameinstance), which is what you're trying to avoid.

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

So you're fine.

所以你很好。

回答by Ken Liu

In a nutshell - you can have two String objects that contain the same characters but are different objects (in different memory locations). The == operator checks to see that two references are pointing to the same object (memory location), but the equals() method checks if the characters are the same.

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

Usually you are interested in checking if two Strings contain the same characters, not whether they point to the same memory location.

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

回答by Laurence Gonsalves

assertEqualsuses the equalsmethod for comparison. There is a different assert, assertSame, which uses the ==operator.

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

To understand why ==shouldn't be used with strings you need to understand what ==does: it does an identity check. That is, a == bchecks to see if aand brefer to the same object. It is built into the language, and its behavior cannot be changed by different classes. The equalsmethod, on the other hand, can be overridden by classes. While its default behavior (in the Objectclass) is to do an identity check using the ==operator, many classes, including String, override it to instead do an "equivalence" check. In the case of String, instead of checking if aand brefer to the same object, a.equals(b)checks to see if the objects they refer to are both strings that contain exactly the same characters.

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

Analogy time: imagine that each Stringobject is a piece of paper with something written on it. Let's say I have two pieces of paper with "Foo" written on them, and another with "Bar" written on it. If I take the first two pieces of paper and use ==to compare them it will return falsebecause it's essentially asking "are these the same piece of paper?". It doesn't need to even look at what's written on the paper. The fact that I'm giving it two pieces of paper (rather than the same one twice) means it will return false. If I use equals, however, the equalsmethod will read the two pieces of paper and see that they say the same thing ("Foo"), and so it'll return true.

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

The bit that gets confusing with Strings is that the Java has a concept of "interning" Strings, and this is (effectively) automatically performed on any string literals in your code. This means that if you have two equivalent string literals in your code (even if they're in different classes) they'll actually both refer to the same Stringobject. This makes the ==operator return truemore often than one might expect.

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