为什么以下表达式评估为假
aStr.replace("H", "H") == "Hello"
而这个替代表达式的计算结果为真?
aStr.replace('H', 'H') == "Hello"
Java在字符串池中缓存String
文字,因此如果没有更改,String
它将从池中获取一个不可变的实例,因此两者都引用内存中的相同实例,因此==
引用返回true
所以要比较字符串对象,你应该使用equals()
方法/compareTo()
方法
另见
该类String
的replace(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()
方法的实现中构造的返回值是新分配的,而不是从实习池中提取的。
字符串比较应该使用.equals()
如果比较是在字符串文字之间进行的,那么 == 比较可能会起作用,因为文字缓存在池中并引用相同的变量。
equals()
比较值,==
比较参考。
使用 String.equals () 比较字符串。
System.out.println((aStr.replace("H","H").equals("Hello")));
将返回true。