小信大的Java例子Shildt

小信大的Java例子Shildt

问题描述:

char ch; 

for (int i = 0; i < 10; i++) { 
    ch = (char) ('a' + i); 
    System.out.print(ch); //<- output small letter 
    ch = (char) ((int) ch & 65503); //<-- ??? 
    System.out.print(ch + " "); 
} 

请解释代码的一部分ch = (char) ((int) ch & 65503);小信大的Java例子Shildt

为什么我们需要65503这个?

+0

这是一个破解(和坏编码[幻数])。一般来说,字符的算术运算在很窄的范围内是有效的,所以它通常是混乱的,不能以自然的方式扩展。另外,真正的案例更改需要特定于语言环境。参见['String toLowerCase(Locale locale)'](https://docs.oracle.com/javase/7/docs/api/java/lang/String.html#toLowerCase(java.util.Locale)) –

Java使用UTF-16字符。这些字符需要2个字节。数量65503有

1111 1111 1101 1111 
      ^  // only the 6th bit is 0 

位模式正如你可以看到只有第6位为0。当你用这个号码作为bit-mask并做位与操作(您char & 65503)它变成了第6那个char关闭(使其为零)。

如果你看看ASCII table(ASCII和Unicode与拉丁字母相同),你会发现第6位是大写字母和非大写拉丁字母之间的差异(数值差异恰好为32) 。所以如果你有小拉丁字符,他们会变成大写字母。如果你有大写字母,它什么都不会做,因为它们的第6位已经是0.所以基本上对于拉丁字符的UpperCase()是一个破解。

+0

谢谢,是的,现在全部清楚 –

+0

@迪拜比兰不客气,加票并接受答案。 – Dmitry

+0

我认为你使用的术语拉丁字母太窄。对于[C0控制和基本拉丁区块](http://www.unicode.org/charts/nameslist/index.html)中的所有字母都是如此,但只有部分C1控件和扩展拉丁文中的字母-1块,在拉丁扩展-1块中没有,......。 –