2012-04-28 52 views
2

可有人请阐明这病巫术一些轻:如何评估相同的表达?

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 

我不知道是怎么回事,但我发誓,我得到了这些结果。我真的没有看到任何区别,并且结果是一致的 - 同样,当我复制一个“假线”时,我又会变得错误,反之亦然。

+0

试着再次运行它,看看你得到了什么。他们都应该是'真实的'。 – 2012-04-28 05:08:15

+1

如果这不仅仅是你拖动我们,请提供一些关于使用的JVM的信息。另外尝试使用像UTF-8这样的unicode编码将字符串转换为字节数组,并比较这些数组。 – Thomas 2012-04-28 05:09:19

+1

对不起,你的结果根本不可能。 – wattostudios 2012-04-28 05:12:01

回答

1

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

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

出现这样

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

这个拷贝到你的IDE和这些字符就不会出现,但它们的存在。 ;)

+1

BOM导致了这个问题(我的答案中有更多信息),并且由于它是不可显示的字符,我已经更新了这个接受的答案。 – Bloke 2012-04-28 14:53:43

+0

奇怪,我的中间3个字符出现在我的IDE上。 – 2012-04-28 15:27:24

2

我不知道发生了什么,因为当我复制所有代码时,每行打印true

因此,将其全部复制回您的机器,并且应该修复所有问题。

如果我不得不猜测,我猜测其中一个“a”字符有一个变音标记,它正在被显示字体映射为没有标记的字符。

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

+0

我想是这样的: 'System.out.println((“a”.getBytes())); // [B @ 18fe7c3 System.out.println((“a”.getBytes())); // [B @ b8df17 \t \t System.out.println((“Joachim Garraud”.getBytes())); // [B @ 13e8d89 System.out.println((“Joachim Garraud”.getBytes())); // [B @ 1be2d65' 但奇怪的是输入了“a”。“Joachim”是来自文件,但我自己输入了“a”来检查这种疯狂。 ..它让我疯狂。 无论如何,谢谢你们的字节检查技巧。 – Bloke 2012-04-28 05:36:30

+1

这有点帮助,但不是很多。你所做的只是表明它们是不同的物体。您没有打印出字节数组的内容。 – 2012-04-28 06:07:03

+0

哦,对。为什么我觉得......哦,好。感谢您指出这一点,现在我已经将它们印出来了,我明白那里发生了什么。现在写答案。 – Bloke 2012-04-28 11:32:07

3

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

+0

看起来像是这样,你可以检查我的评论到@Old Pro的答案,看看我用'getBytes()'得到的字节。谢谢。 我会选择你的答案作为接受的答案,因为这一定是发生了什么(虽然我仍然很困惑,因为我自己输入了_a_)。不过,我希望我也可以赞扬@Thomas和@Old Pro,他们用字节数组技巧解决了这个问题。 – Bloke 2012-04-28 05:46:53

+0

@Block - 您可以通过提高他们的答案来给予奖励。 – 2012-04-28 06:09:30

+0

没有足够的声誉呢.. – Bloke 2012-04-28 11:27:42

3

打印出字符串的二进制代码(由托马斯和老专业版)的建议后,它终于证明,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 

现在我可以用约阿希姆·加拉德明白这一点,因为我从两个不同的.txt文件得到了那些“两节” - 第一次是在beginni第一个文件,第二个文件位于第二个文件的中间。 但是,我输入了a的我自己,但是不记得我是怎么做到的 - 也许我用复制粘贴了一段代码和假评估表达式,然后删除Joachim Garraud在报价单内并键入a,这并未删除BOM。

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

+1

是的......你应该使用“Jon Skeet”。他会是SO的官方Chuck Norris :-) – 2012-04-28 15:02:00