【问题标题】:How does java handle unicode characters?java如何处理unicode字符?
【发布时间】:2011-11-20 22:14:29
【问题描述】:

我阅读了this blogentry 关于 perl 以及它们如何处理 unicode 和 unicode 规范化的内容。 据我了解,简短版本是有几种方法可以用 unicode 编写标识符“é”。作为一个 unicode 字符或作为两个字符的组合。而且perl程序可能无法区分它们导致奇怪的错误。

这让我想到,Eclipse 中的 Java 编辑器如何处理 unicode?或者一般的java,因为我猜那是同一个问题。

一方面specification 说:

两个标识符只有相同时才相同,即每个字母或数字具有相同的 Unicode 字符。

但另一方面,unicode 字符被翻译:

此转换步骤允许任何程序仅使用 ASCII 字符表示。

这似乎相互矛盾?

【问题讨论】:

    标签: java eclipse unicode


    【解决方案1】:

    将字符表示为 Unicode 转义不同于 Unicode 组合字符。

    据我了解,有几种方法可以用 unicode 编写标识符“é”。可以是一个 unicode 字符,也可以是两个字符的组合。

    具体来说,é 可以由单个代码点 U+00E9 或组合序列 U+0065 U+0301 表示。这些表格是NFC and NFD respectively,您可以在它们之间进行标准化。

    Java 编译器不执行规范化,所以这是合法的:

    public class EAcute {
      int \u00E9;
      int \u0065\u0301; 
    }
    

    ...即使表示为文字字素,似乎存在冲突:

    public class EAcute {
      int é;
      int é; 
    }
    

    这是编码为 UTF-8 的后一种形式的十六进制转储:

    0000000: 7075 626c 6963 2063 6c61 7373 2045 4163  public class EAc
    0000010: 7574 6520 7b0a 2020 696e 7420 c3a9 3b0a  ute {.  int ..;.
    0000020: 2020 696e 7420 65cc 813b 200a 7d0a         int e..; .}.
    

    因此,虽然 é (C3A9) 和 \u00E9é (65CC82) 和 \u0065\u0301 被编译器视为等效,但其他组合则不是。

    【讨论】:

      【解决方案2】:

      规范说 Unicode 可以用 ASCII 的形式表示:

      \uxxxx
      

      其中字符“\”、“u”是 ASCII 字符,“xxxx”是十六进制(因此可以用 ASCII 表示)。

      这意味着他们已经将 Unicode 和 ASCII 之间的转换形式化为 Java 编程语言。 Java 编程语言的所有实现者现在都可以支持 ASCII 和 Unicode 编辑器,并且类似地将堆栈跟踪等输出到 ASCII 或 Unicode 系统。

      【讨论】:

        【解决方案3】:

        翻译步骤是指词汇翻译过程的第一步:

        将原始 Unicode 字符流中的 Unicode 转义(第 3.3 节)翻译成相应的 Unicode 字符。 \uxxxx 形式的 Unicode 转义,其中 xxxx 是十六进制值,表示编码为 xxxx 的 Unicode 字符。此转换步骤允许任何程序仅使用 ASCII 字符来表示。

        词法转换过程允许在您的源代码中将 Unicode 字符指定为仅包含 ASCII 字符的转义序列。因此,可以使用有效的 Unicode 字符命名标识符,但使用 Unicode 转义序列以 ASCII 表示。

        转义序列的转换发生在调用编译器生成字节码之前;是编译器验证两个标识符是否相似,无论它们在代码中如何表示。编译器提供了输入字符和行终止符的规范化序列,并且针对该序列应用了命名标识符的规则。因此,以下代码将无法编译,并且会产生错误,因为标识符具有相同的名称,尽管表示方式不同:

        package info.example.i18n;
        
        public class UnicodeEscape
        {
            int a;
            int \u0061; // Hex(61) = Dec(97) = 'a' in ASCII-7
        }
        

        【讨论】:

        • 很好的答案。刚刚测试和“int \u00E9; int \u0065\u0301;”即使它们都是字符“é”也可以使用
        猜你喜欢
        • 1970-01-01
        • 2018-12-05
        • 2010-11-01
        • 2012-03-03
        • 1970-01-01
        • 1970-01-01
        • 2011-02-22
        • 2013-12-30
        • 2010-12-11
        相关资源
        最近更新 更多