如何以不同的方式评估相同的表达式?

时间:2012-04-28 05:00:43

标签: java string boolean equals

有人可以对这种生病的巫术有所了解:

    System.out.println(("a".equals("a")));  //true
    System.out.println(("a".equals("а")));  //false

    System.out.println(("Joachim Garraud" == "Joachim Garraud"));       //true
    System.out.println(("Joachim Garraud" == "Joаchim Garraud"));       //false
    System.out.println(("Joachim Garraud".equals("Joаchim Garraud")));  //false
    System.out.println(("Joachim Garraud".equals("Joachim Garraud")));  //true

我不知道这里发生了什么,但我发誓我得到了这些结果。我真的没有看到任何差异,结果是一致的 - 当我复制一个“假行”时,我再次假,反之亦然。

4 个答案:

答案 0 :(得分:3)

我怀疑原因是您的代码包含(例如)"a"字符的不同版本。例如,小写的LATIN A可能看起来与小写的CYRILIC A相同......但它们是不同的Unicode代码点(\u0061\u0430),因此不相等。

答案 1 :(得分:3)

打印出字符串的二进制代码后(正如Thomas和Old Pro所建议的那样),最终证明BOM导致了不平等:

for( byte b : "a".getBytes() ) { // The first "a" copied from the false-expression
    System.out.printf("%x ", b);
}
for( byte b : "a".getBytes() ) { // The second "a" copied from the false-expression
    System.out.printf("%x ", b);
}

// Again, copied from the false-evaluating expression:
for( byte b : "Joachim Garraud".getBytes() ) {
    System.out.printf("%x ", b);
}
for( byte b : "Joachim Garraud".getBytes() ) {
    System.out.printf("%x ", b);
}

...导致以下输出:(打印输出对齐以提高可读性)

ef bb bf 61
         61

ef bb bf 4a 6f 61 63 68 69 6d 20 47 61 72 72 61 75 64 
         4a 6f 61 63 68 69 6d 20 47 61 72 72 61 75 64

现在我可以用 Joachim Garraud 理解这一点,因为我从两个不同的.txt文件中得到了那些“两个” - 第一个文件位于第一个文件的开头,第二个文件位于第一个文件的某个位置。第二个文件的中间。 然而,我自己键入了 a ,但我不记得我是怎么做到的 - 也许我用错误复制粘贴了一段代码 - 评估表达式,然后在引号内删除 Joachim Garraud 并键入 a ,但未删除BOM。

无论如何,我希望可以从中学到一些东西。此外,这家伙在这里得到了很多免费广告(实际上是BOM),虽然我认为他是某种新的查克诺里斯。不是粉丝或任何东西。

答案 2 :(得分:2)

我也不知道发生了什么,就像我在每行打印true时复制了所有代码一样。

所以将它们全部复制回你的机器,一切都应该修复。

如果我不得不猜测,我猜其中一个“a”字符有一个变音标记,由你的显示字体映射到一个没有标记的字符。

下次以十六进制打印出字符串的二进制代码并进行比较。

答案 3 :(得分:1)

您还应该查找不可显示的字符。

System.out.println("<\ufff9\ufffa\ufffb>");
System.out.println("<>");
System.out.println("<>".length());
System.out.println(Arrays.toString("<>".toCharArray()));

看起来像这样

<>
<>
5
[<, , , , >]

将其复制到您的IDE中,这些字符不会出现,但它们就在那里。 ;)