java如何处理unicode字符?

时间:2011-09-20 09:24:33

标签: java eclipse unicode

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

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

一方面specification说:

  

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

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

  

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

这似乎相互矛盾?

3 个答案:

答案 0 :(得分:5)

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

  

将原始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
}

答案 1 :(得分:5)

将字符表示为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 :(得分:1)

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

\uxxxx

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

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