4

为什么以下表达式评估为假

aStr.replace("H", "H") == "Hello"

而这个替代表达式的计算结果为真?

aStr.replace('H', 'H') == "Hello"
4

4 回答 4

4

Java在字符串池中缓存String文字,因此如果没有更改,String它将从池中获取一个不可变的实例,因此两者都引用内存中的相同实例,因此==引用返回true

所以要比较字符串对象,你应该使用equals()方法/compareTo()方法


另见

于 2012-09-28T19:11:36.903 回答
2

该类Stringreplace(char, char)方法扫描寻找匹配的字符。如果没有找到,它会String按原样返回主机实例。自然地,通过==运算符将返回的引用与原始引用进行比较返回 true,因为这是测试引用相等性,并且两个引用是相同的。

但是,如果原始字符串包含一个 'H' 字符(使用您的示例在这里),那么返回的字符串将原始字符串不同(即使它将逐个字符相同);它将是一个新分配的实例,它将通过引用相等(同样是==运算符)进行比较失败。将返回值String与原始 via 进行比较Object#equals()将返回 true,因为这两个字符串是等效的,但它们将是无法通过引用相等性匹配的不同实例。

相比之下,String#replace(CharSequence, CharSequence)将目标字符串视为正则表达式;它Matcher#replaceAll()在内部使用提供的替换序列替换目标模式中的匹配项。

Matcher#replaceAll()现在问题归结为即使模式匹配,是否会返回原始字符串或新分配的副本。通过阅读 Oracle 库中的代码,如果Matcher找不到匹配的模式,它会返回CharSequence#toString()original CharSequence,对于String对象来说,它只会返回未受干扰的this引用。这让我想知道你是否在这里报告了真实的结果。

所提出的问题中一个明显的漏洞是String引用的原始内容aStr。您可能打算显示一个声明,例如

final String aStr = "Hello";

但你没有。两个表达式的结果应取决于是否aStr包含“H”字符。假设它确实如此,我希望这两个表达式都产生错误,假设任何一个重载都没有字符串实习。String#replace()我们知道字符串文字是实习的,但是我们看到在 Oracle 库的这两种String#replace()方法的实现中构造的返回值是新分配的,而不是从实习池中提取的。

于 2012-10-05T00:07:45.643 回答
2

字符串比较应该使用.equals()

如果比较是在字符串文字之间进行的,那么 == 比较可能会起作用,因为文字缓存在池中并引用相同的变量。

equals()比较值,==比较参考。

于 2012-09-28T19:11:37.060 回答
0

使用 String.equals () 比较字符串。

        System.out.println((aStr.replace("H","H").equals("Hello")));

将返回true

于 2012-09-28T19:13:25.937 回答