Reputation: 1013
I would like to check if strings are accidentally compared with the == operator. My approach is to try to create new strings in the testcases instead of using string literals, so that comparisons like actualString == testParameter evaluate to false in the test subject, even though the contents of the strings are equal. This hopefully creates unexpected behaviour and leads to test failure. To do this I need to create a new string object in Java. How can I do so reliably?
String a = "I am the same.";
String b = "I am the same."; // Does not create a new String.
String c = new String("I am the same.");
String d = new StringBuilder().append("I am the same.").toString();
Are the last two lines guaranteed to create new string objects? If you know of another approach, please let me know.
Upvotes: 1
Views: 661
Reputation: 2405
The javadoc of the String class states that it creates a new String with a copy of the passed argument. So it is guaranteed to be a new instance.
Initializes a newly created {@code String} object so that it represents the same sequence of characters as the argument; in other words, the newly created string is a copy of the argument string. Unless an explicit copy of {@code original} is needed, use of this constructor is unnecessary since Strings are immutable.
Upvotes: 0
Reputation: 328618
"I am the same." == new String("I am the same.")
is guaranteed to be false.
BUT, instead of unnecessarily cluttering your tests, you should use a static analysis tool, such as FindBugs, which has a rule just for that:
Comparison of String objects using == or != (ES_COMPARING_STRINGS_WITH_EQ)
Upvotes: 7
Reputation: 813
If you use ==
to compare objects it will check if it's the same object so it checks if the memory addresses of the objects are the same.
The string class overrides the equals() method and checks for content.
If you're creating a string like this
String s1 = "Hi";
Java will put "Hi" in the so called string literal pool so if you are creating a second string
String s2 = "Hi";
Java will not create a second Object but will refer to the "Hi" in the string literal pool.
Now you could do compare the two strings like s1 == s2
and it would be true because the two references s1 and s2 point to the same object.
What the sb.toString()
method internally does is new String()
and if you declare a string like this a new object will be created and the comparison with ==
will return false because the two references obviously don't point at the same object.
Upvotes: 0