能够回答为什么Unicode转义被实现的唯一的人是编写规范的人。
一个似是而非的理由是,希望允许整个BMP成为Java源代码的可能字符。这提出了一个问题:
当Unicode转义进入战斗时,这是非常困难的:它创建了一整套新的词法分析器规则。
最简单的方法是分两步执行lexing:首先使用它所代表的字符搜索并替换所有Unicode转义符,然后解析生成的文档,就好像Unicode转义不存在一样。
这样做的好处在于它易于指定,因此它使规范更简单,并且易于实现。
不好的是,你的榜样。
编译器不仅会在将程序解析为标记之前将Unicode转义转换为它们所代表的字符,而是在丢弃注释和空格之前进行转换。
该程序包含一个Unicode转义符(\ u000d),位于其唯一注释中。正如评论告诉您的那样,此转义表示换行符,编译器会正确转换它 在放弃评论之前 。
这与平台有关。在某些平台上,例如UNIX,它可以工作;在其他方面,例如Windows,它不会。虽然肉眼可能看起来相同,但如果将其保存在文件中或通过管道传输到另一个程序进行后续处理,则很容易引起问题。
我同意@zwol这是一个设计错误;但我更加批评它。
\u escape在string和char文字中很有用;这是唯一应该存在的地方。应该像处理其他转义一样处理它 \n ;和 "\u000A" 应该 确切地说 "\n" 。
\u
\n
"\u000A"
"\n"
绝对没有意义 \uxxxx 在评论中 - 没有人能读到这一点。
\uxxxx
同样,没有必要使用 \uxxxx 在该计划的其他部分。唯一的例外可能是在强制包含一些非ascii字符的公共API中 - 我们最后一次看到它是什么?
设计师在1995年有他们的理由,但20年后,这似乎是一个错误的选择。
(向读者提问 - 为什么这个问题不断获得新的选票?这个问题是否从流行的地方联系起来?)
这是一个有意的设计选择,一直回到Java的原始设计。
对于那些问“谁想要在评论中逃脱Unicode?”的人,我认为他们是那些母语使用拉丁字符集的人。换句话说,Java的原始设计中固有的,人们可以在Java程序中的任何合法地方使用任意Unicode字符,最常见的是在注释和字符串中。
可以说,用于查看源文本的程序(如IDE)的缺点是这些程序无法解释Unicode转义并显示相应的字形。
我将完全无效地添加这一点,仅仅是因为我无法帮助自己而我还没有看到它,这个问题是无效的,因为它包含一个错误的隐藏前提,即代码在一条评论!
在Java源代码中,\ u000d在各方面都与ASCII CR字符等效。无论它出现在哪里,它都是一个简单明了的行。问题中的格式是误导性的,字符序列实际上在语法上对应的是:
public static void main(String... args) { // The comment below is no typo. // System.out.println("Hello World!"); }
恕我直言,最正确的答案是:代码执行,因为它不在评论中;它在下一行。 Java中不允许“在注释中执行代码”,就像您期望的那样。
大部分混淆源于语法高亮显示器和IDE不够复杂以考虑这种情况。它们要么根本不处理unicode转义,要么在解析代码之后而不是之前处理它,比如 javac 确实。
javac