【问题标题】:Unicode in javadoc and comments?javadoc和注释中的Unicode?
【发布时间】:2012-05-08 22:37:47
【问题描述】:

一些编译器在 JavaDoc 和源代码 cmets 中无法处理非 ASCII 字符。关于 Java 源文件中的 Unicode,当前(Java 7)和未来(Java 8 及更高版本)实践是什么? IcedTea、OpenJDK 和其他 Java 环境之间是否存在差异,语言规范规定了什么?是否应该在 JavaDoc 中使用类似 HTML &escape; 的代码对所有非 ASCII 字符进行转义?但是 Java // 注释 等价物是什么?

更新:cmets表示可以使用任何字符集,编译时需要指出源文件中使用的是什么字符集。我将对此进行研究,并将寻找有关如何通过 Ant、Eclipse 和 Maven 进行配置的详细信息。

【问题讨论】:

  • 看看this(我确定这是JLS指定的)。
  • 其实你可以在你的源文件中使用任何你想要的编码,你只需要在Java编译器和javadoc命令行中指明你选择了哪一种。
  • 好的,这就是我要找的信息!首先,这很酷,并且没有意识到这一点。所以,现在我只需要弄清楚如何让编译器知道要使用什么字符集...例如,CDK 是使用 Ant、Maven 和 Eclipse 编译的...

标签: java unicode comments javadoc


【解决方案1】:

正如评论者所指出的,源文件的编码可以传递给(至少一些)编译器。在这个答案中,我将总结如何传递这些信息。

Eclipse

Eclipse(3.7 已选中)不需要任何特殊配置,您可以愉快地使用 Java 源代码,例如:

double π = Math.PI;

蚂蚁

<javac encoding="UTF-8" ... >
</javac>

Java

javac -encoding UTF-8 src/main/Foo.java

Gradle

javadoc {
    options.encoding = 'UTF-8'
}

【讨论】:

    【解决方案2】:

    一些编译器在 JavaDoc 和源代码 cmets 中的非 ASCII 字符上失败。

    这可能是因为编译器假定输入为 UTF-8,并且源文件中存在无效的 UTF-8 序列。这些似乎在源代码编辑器中的 cmets 中是无关紧要的,因为词法分析器(将 cmets 与其他标记区分开来)永远不会运行。当工具在词法分析器运行之前尝试将字节转换为字符时发生故障。


    javacjavadocman 页面说

    -encoding name
              Specifies  the  source  file  encoding   name,   such   as
              EUCJIS/SJIS.   If  this option is not specified, the plat-
              form default converter is used.
    

    所以使用编码标志运行javadoc

    javadoc -encoding <encoding-name> ...
    

    在将&lt;encoding-name&gt; 替换为您用于源文件的编码后,它应该会使用正确的编码。

    如果您在需要一起编译的一组源文件中使用了多个编码,则需要先解决该问题,然后为所有源文件确定一个统一的编码。你真的应该只使用 UTF-8 或坚持使用 ASCII。


    关于 Java 源文件中的 Unicode,当前(Java 7)和未来(Java 8 及更高版本)的做法是什么?

    Java中处理源文件的算法是

    1. 收集字节
    2. 使用某种编码将字节转换为字符(UTF-16 代码单元)。
    3. 用对应于这些十六进制数字的代码单元替换所有'\\''u' 后跟四个十六进制数字的序列。如果 "\u" 后面没有四个十六进制数字,则会出错。
    4. 将字符转换为标记。
    5. 将标记解析为类。

    当前和以前的做法是,第 2 步,将字节转换为 UTF-16 代码单元,取决于加载编译单元(源文件)的工具,但命令行界面的实际标准是使用-encoding 标志。

    转换完成后,语言要求在词法分析和解析之前将\uABCD 样式序列转换为 UTF-16 代码单元(第 3 步)。

    例如:

    int a;
    \u0061 = 42;
    

    是一对有效的 Java 语句。 任何 java 源代码工具都必须在将字节转换为字符之后但在解析之前查找 \uABCD 序列并对其进行转换,以便将这段代码转换为

    int a;
    a = 42;
    

    在解析之前。无论 \uABCD 序列出现在何处,都会发生这种情况。

    这个过程看起来像

    1. 获取字节:[105, 110, 116, 32, 97, 59, 10, 92, 117, 48, 48, 54, 49, 32, 61, 32, 52, 50, 59]
    2. 将字节转换为字符:['i', 'n', 't', ' ', 'a', ';', '\n', '\\', 'u', '0', '0', '6', '1', ' ', '=', ' ', '4', '2', ';']
    3. 替换 unicode 转义:['i', 'n', 't', ' ', 'a', ';', '\n', a, ' ', '=', ' ', '4', '2', ';']
    4. 莱克斯:["int", "a", ";", "a", "=", "42", ";"]
    5. 解析:(Block (Variable (Type int) (Identifier "a")) (Assign (Reference "a") (Int 42)))

    是否应该在 JavaDoc 中使用 HTML &escape;-like 代码对所有非 ASCII 字符进行转义?

    除了您希望在文档中直接出现的 HTML 特殊字符(如 '&lt;')外,无需其他字符。您可以在 javadoc cmets 中使用 \uABCD 序列。 Java 在解析源文件之前处理\u....,以便它们可以真正出现在字符串、cmets 中,任何地方。这就是为什么

    System.out.println("Hello, world!\u0022);
    

    是一个有效的 Java 语句。

    /** @return \u03b8 in radians */
    

    等价于

    /** @return θ in radians */
    

    就 javadoc 而言。


    但是,Java // 评论等效项是什么?

    您可以在 java 中使用 // cmets,但 Javadoc 仅在 /**...*/ cmets 内部查找文档。 // cmets 不携带元数据。

    Java 处理\uABCD 序列的一个结果是,虽然

    // Comment text.\u000A System.out.println("Not really comment text");
    

    看起来像单行注释,许多 IDE 会这样突出显示它,但不是。

    【讨论】:

    • java 工具会尊重 emacs/vim 关于编码的元数据吗?
    • @Marcin,如果你的意思是像 // -*- coding: UTF-8 -*- 这样在文件开头的评论,工具可以选择这样做,但 Sun 工具不会 AFAIK。
    • @Marcin,是的。源代码编码是一个 PITA。许多较新的语言强制或强烈建议将 UTF-8 作为其源文件的编码格式。 JSONPython 默认“默认编码为 UTF-8”、“默认为 UTF-8”。 GoRust 更严格:“源代码是以 UTF-8 编码的 Unicode 文本”,“输入被解释为以 UTF-8 编码的 Unicode 代码点序列。” Java 应该用于-source 1.7
    猜你喜欢
    • 2015-11-02
    • 2016-07-19
    • 2013-12-15
    • 2012-03-17
    • 1970-01-01
    • 2012-02-23
    • 2017-09-08
    • 1970-01-01
    • 2012-03-03
    相关资源
    最近更新 更多