为什么以下表达式评估为false
aStr.replace("H", "H") == "Hello"
虽然这个替代表达式的评估结果是真的吗?
aStr.replace('H', 'H') == "Hello"
答案 0 :(得分:4)
Java在字符串池中缓存String
字面值,因此如果String
中没有更改,则会从池中获取不可变实例,因此两者都引用内存中的相同实例,因此{{1引用返回==
因此,要比较字符串对象,您应该使用true
方法/ equals()
方法
另见
答案 1 :(得分:2)
应使用.equals()
如果比较是在字符串文字之间,则==比较可能有效,因为文字被缓存在池中并引用相同的变量。
equals()
比较值,==
比较参考。
答案 2 :(得分:2)
String
类的replace(char, char)
方法会扫描以查找匹配的字符。如果找不到,则返回主机String
实例。当然,通过==
运算符将返回的引用与原始引用进行比较会返回true,因为它正在测试引用相等,并且这两个引用是同一个。
但是,如果原始字符串包含' H'字符 - 在这里使用你的例子 - 然后返回的字符串将不与原始字符串相同(即使它将是相同的逐个字符);它将是一个新分配的实例,它将无法通过引用相等性进行比较(同样,==
运算符)。将返回的String
与原始的Object#equals()
进行比较将返回true,因为两个字符串等效,但它们将是通过引用相等而无法匹配的不同实例。< / p>
相比之下,String#replace(CharSequence, CharSequence)
将目标字符串视为正则表达式;它在内部使用Matcher#replaceAll()
来替换目标模式中的匹配项,并使用提供的替换序列。
现在问题归结为Matcher#replaceAll()
是否会返回原始字符串或新分配的副本,即使模式不匹配也是如此。通过阅读Oracle库中的代码,如果Matcher
找不到匹配的模式,则会在原CharSequence#toString()
上返回CharSequence
,String
为this
1}}对象只返回未调整的String
引用。这让我想知道你是否在这里报告了真实的结果。
提出的问题中一个明显的漏洞是aStr
引用的final String aStr = "Hello";
的原始内容。你可能想要显示一个像
aStr
但你没有。这两个表达式的结果应取决于String#replace()
是否包含&#39; H&#39;性格与否。假设确实如此,我认为两个表达式都会产生错误,假设任何String#replace()
重载都没有string interning。我们知道字符串文字是实习的,但是我们在Oracle库的两个{{1}}方法的实现中构建的返回值是新分配的,而不是从实习池中提取的。
答案 3 :(得分:0)
使用String.equals()来比较字符串。
System.out.println((aStr.replace("H","H").equals("Hello")));
将返回 true 。