Java 如何用Unicode编写程序?

Java 如何用Unicode编写程序?,java,unicode,character-encoding,javac,Java,Unicode,Character Encoding,Javac,来自Java规范SE7版 §3.1Unicode 程序是使用Unicode字符集编写的 §3.2词汇翻译 原始Unicode字符流被转换为 标记,使用以下三个词汇翻译步骤 我很困惑,因为我用我的本机字符编码(Windows-1252)编写源代码,规范提到(?)都从原始Unicode字符流开始,然后执行词法转换(包括Unicode转义转换) 他们提到Unicode转义可以用于包含任何使用 只有ASCII字符;如果执行以前的转换,我认为它们引用Unicode字符集子集中的ASCII字符,这是有意义的

来自Java规范SE7版

§3.1Unicode

程序是使用Unicode字符集编写的

§3.2词汇翻译

原始Unicode字符流被转换为 标记,使用以下三个词汇翻译步骤

我很困惑,因为我用我的本机字符编码(Windows-1252)编写源代码,规范提到(?)都从原始Unicode字符流开始,然后执行词法转换(包括Unicode转义转换)

他们提到Unicode转义可以用于包含任何使用 只有ASCII字符;如果执行以前的转换,我认为它们引用Unicode字符集子集中的ASCII字符,这是有意义的

是否有以前将源文件写入Unicode时使用的编码转换

有些信息是相关的,但我认为这更像是运行时的文本处理,而不是编译过程:


规范的基本意思是,您只能在源文件中使用Unicode字符。它没有定义这些字符实际上是如何编码成字节的,这取决于您和您正在使用的平台

基本上,编译器内部的工作是将源文件作为字节流从磁盘读取,然后将这些字节转换为Java的Unicode字符内部表示形式。它将源文件的原始字节转换为Unicode字符的方式基于传递给
javac
-encoding
选项。如果未设置
-encoding
选项,则将使用平台的默认编码


现在还需要注意的是,在编译器将源代码字节转换为字符后,它会执行另一个步骤将字符文本(例如
\u00a5123
)转换为相应的单个Unicode字符。这实际上是您在问题中引用的第3.2节中提到的三个步骤中的第一个。这样,就可以只使用普通ASCII字符来表示源代码中的任何Unicode字符。

'Unicode'不是一种编码,它只是字符和关联数字(或“代码点”)的列表,但与传统字符集不同的是,数字不是Unicode字符的磁盘表示形式。要对Unicode字符进行编码或解码,您需要一个单独的编码,它将字节序列映射到Unicode数字,从而映射到Unicode字符

有些编码,如UTF-8,设计用于对所有可能的Unicode码点进行编码。其他的,如WindowsCP1252,只能表示Unicode字符的一小部分。但任何有效的WindowsCP1252数据仍然可以解码为有效的Unicode码点序列


因此,是的,可以将磁盘上的表示转换为虚拟的Unicode字符流。

您的编译器可能能够将源代码文件转换为内部Unicode表示。对于语言规范而言,实际物理文件的格式并不重要。CP-1252是一种编码,规范涉及字符集。CP-1252支持的所有字符实际上都包含在Unicode字符集中。是的,Unicode的处理方式(字符集或编码)会导致混淆,但看看我发布的链接(官方文档),他们说:Unicode是一种支持世界主要语言的16位字符编码,所以我不知道如何引用它,感谢您告知文档不正确。即使我们避免将Unicode的引用作为编码来挑剔,那么他们说它是“16位”仍然是错误的。事实上,当以二进制表示时,Unicode代码点最多需要21位。Unicode联盟承诺不使用更大的值来保持与UTF-16的兼容性,但在此之前,Unicode可以使用高达31位的值来与UTF-32和UTF-8(6字节版本)兼容。如果不希望与这些编码中的任何一种保持兼容,那么就没有限制了。这是否意味着您可以用这些代码来编写所有源代码:\u00a5123?@RobertMarkBram我不确定Java,但是C和C++允许Unicode逃逸,但是禁止它们用于字符串和字符文本之外的基本源字符集中的字符。我猜Java也有同样的限制,所以你不能这样写代码。@RobertMarkBram Hello World程序使用转义序列:\u0057\u0068\u0079\u0020\u0077\u006F\u0075\u006C\u0064\u0020\u0079\u006F\u0075\u0020\u0077\u0061\u006E\u0074\u0020\u0064\u006F\u0020\u0074\u0068\u0074\u003F@nEAnnam哇!我想Java没有禁止这样做的规定。Java的UCS规范中还有一个错误。(另一个原因是Java使用UCS的代理项对来表示BMP之外的字符。)