我想检查字符串是否与==运算符意外地进行了比较。我的方法是尝试在测试用例中创建新字符串,而不是使用字符串文字,这样,在测试主题中, actualString == testParameter 等比较评估为false,即使字符串的内容相等。这有望产生意外行为并导致测试失败。为此,我需要在Java中创建一个新的字符串对象。我怎么能可靠地这样做?
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();
最后两行是否可以保证创建新的字符串对象? 如果您知道其他方法,请告诉我。
答案 0 :(得分:7)
"I am the same." == new String("I am the same.")
保证是假的。
但是,你应该使用一个静态分析工具,比如FindBugs,而不是不必要地混乱你的测试,它只有a rule:
使用==或!=(ES_COMPARING_STRINGS_WITH_EQ)比较String对象
答案 1 :(得分:0)
如果使用==
来比较对象,它将检查它是否是同一个对象,以便检查对象的内存地址是否相同。
字符串类重写equals()方法并检查内容。
如果你要创建像这样的字符串
String s1 = "Hi";
Java会把#34;嗨"在所谓的字符串文字池中,所以如果你要创建第二个字符串
String s2 = "Hi";
Java不会创建第二个对象,但会引用" Hi"在字符串文字池中。
现在你可以比较像s1 == s2
这样的两个字符串,这是真的,因为两个引用s1和s2指向同一个对象。
sb.toString()
方法内部执行的操作是new String()
,如果您声明这样的字符串,则会创建一个新对象,并且与==
的比较将返回false,因为这两个引用显然是不要指向同一个物体。
答案 2 :(得分:0)
String类的javadoc声明它创建了一个带有传递参数副本的新String。所以它保证是一个新的实例。
初始化一个新创建的{@code String}对象,使其代表 与参数相同的字符序列;换句话说, 新创建的字符串是参数字符串的副本。除非 需要{@code original}的显式副本,使用此构造函数是 因为字符串是不可变的,所以不必要。