3

我遇到了以下代码:

public class LinePrinter {
    public static void main(String args[]) {
      //Note: \u000A is unicode for Line Feed
      char c=0x000A;
      System.out.println(c);
    }
}

由于已完成 Unicode 替换,因此无法编译。

问题是,为什么注释( //) 不覆盖编译器完成的 Unicode 替换?我认为编译器应该先忽略注释,然后再对代码翻译做任何其他事情。

编辑:

不确定以上是否足够清楚。

我知道上面会发生什么以及为什么会出错。我的期望是编译器在对代码进行任何翻译之前应该忽略所有注释行。显然这里不是这样。我期待这种行为的基本原理。

4

2 回答 2

5

它在 Java Puzzlers # 14 - 解释的摘录:

理解这个难题的关键是 Java 没有为字符串文字中的 Unicode 转义提供特殊处理。编译器将 Unicode 转义转换为它们所代表的字符,然后再将程序解析为标记,例如字符串文字 [JLS 3.2]。

JLS v7 中的相关段落是第 3.3 段

Java 编程语言的编译器(“Java 编译器”)首先识别其输入中的 Unicode 转义,将 ASCII 字符 \u 后跟四个十六进制数字转换为指示的十六进制值的 UTF-16 代码单元(第 3.1 节),并且传递所有其他字符不变。

JLS 第 3 节的介绍提示了为什么会出现这种情况:

程序是用 Unicode(第 3.1 节)编写的,但提供了词汇翻译(第 3.2 节),因此 Unicode 转义(第 3.3 节)可用于包含仅使用 ASCII 字符的任何 Unicode 字符。

于 2012-12-07T11:09:05.233 回答
2

native2ascii该规范规定,Java 编译器必须在执行任何其他操作之前将 Unicode 转义符转换为其相应的字符,以允许在代码通过非加密通道存储或发送时(通过)保护标识符中的非 ASCII 字符。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 ");

然后将其转义为单行注释,然后在下一个解析阶段将其删除。因此不会产生编译器错误或警告,而是默默地删除一整行代码......

于 2012-12-07T11:35:40.017 回答