我遇到了以下代码:
public class LinePrinter {
public static void main(String args[]) {
//Note: \u000A is unicode for Line Feed
char c=0x000A;
System.out.println(c);
}
}
由于Unicode替换完成,因此无法编译。
问题是, comment (//
)为什么不覆盖编译器完成的Unicode替换?我认为在使用代码转换执行任何其他操作之前,编译器应首先忽略注释。
修改
不确定上述内容是否足够清晰。
我知道上面会发生什么以及为什么会出错。我的期望是编译器在使用代码进行任何转换之前应该忽略所有注释行。显然情况并非如此。我期待这种行为的理由。
答案 0 :(得分:5)
它是Java Puzzlers#14 - 解释的摘录:
理解这个难题的关键是Java没有为Unicode提供特殊处理 在字符串文字中转义。编译器在将程序解析为标记之前将Unicode转义转换为它们所代表的字符,例如字符串文字[JLS 3.2]。
JLS第7版中的相关段落为paragraph 3.3:
Java编程语言(“Java编译器”)的编译器首先在其输入中识别Unicode转义符,将ASCII字符\ u后跟四个十六进制数字转换为指定十六进制的UTF-16代码单元(第3.1节)值,并传递所有其他字符不变。
JLS第3节的介绍给出了为什么会出现这种情况的提示:
程序是用Unicode(§3.1)编写的,但提供了词法翻译(§3.2),因此Unicode转义(§3.3)可用于包含仅使用ASCII字符的任何Unicode字符。
答案 1 :(得分:1)
规范声明Java编译器在执行任何其他操作之前必须将Unicode转义符转换为其相应的字符,以便在存储代码时允许保护标识符中的非ASCII字符(通过native2ascii
)或通过非8位清洁的频道发送。
此规则适用于全局,尤其是您甚至可以使用Unicode转义符转义注释标记。例如,以下两个片段是相同的:
// Deal with opening and closing comment characters /*, etc.
myRisquéParser.handle("/*", "*/");
\u002F\u002F Deal with opening and closing comment characters /*, etc.
myRisqu\u00E9Parser.handle("/*", "*/");
如果编译器在处理Unicode转义之前尝试删除注释,最终会剥离从/*, etc.
到handle("/*", "*/
的所有内容,而
\u002F\u002F Deal with opening and closing comment characters ");
然后将转义为单行注释,然后在解析的下一阶段删除。因此,不产生编译器错误或警告,而是静静地删除整行代码...