我读了关于perl的this blogentry以及它们如何处理unicode的unicode和规范化。 根据我的理解,简短版本是有几种方法可以在unicode中编写标识符“é”。既可以是一个unicode字符,也可以是两个字符的组合。并且perl程序可能无法区分它们导致奇怪的错误。
这让我思考,Eclipse中的Java编辑器如何处理unicode?或者一般的java,因为我猜这是同样的问题。
一方面specification说:
两个标识符只有相同才有相同之处,即每个字母或数字都有相同的Unicode字符。
但另一方面,unicode字符被翻译成:
此转换步骤允许任何程序仅使用ASCII字符表示。
这似乎相互矛盾?
答案 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系统。