我遇到过“char变量是Unicode格式,但也很好地采用/映射到ASCII”。有什么需要提到的?当然,ASCII是1个字节,Unicode是2.而Unicodeitself中包含ASCII代码(默认情况下 - 它是标准)。那么有些语言中char
变量支持UNICODE但不支持ASCII吗?
另外,字符格式(Unicode / ASCII)由我们使用的平台决定,对吧? (UNIX,Linux,Windows等)。假设我的平台使用ASCII,是不是可以切换到Unicode,反之亦然?
答案 0 :(得分:8)
Java在内部使用Unicode。总是。 实际上,它大部分时间都使用UTF-16,但现在这个细节太多了。
它可以不在内部使用ASCII(例如String
)。 可以表示任何可以用Unicode在ASCII中表示的字符串,因此这不应该是一个问题。
平台发挥作用的唯一位置是Java在未指定编码时必须选择编码的地方。例如,当您创建FileWriter
以将String
值写入字符串时:此时,Java需要使用编码来指定特定字符应如何映射到字节。如果未指定,则使用平台的默认编码。默认编码几乎从不ASCII 。大多数Linux平台使用UTF-8,Windows 通常使用一些ISO-8859- *衍生物(或其他文化特定的8位编码),但当前操作系统没有使用ASCII(因为ASCII不能代表很多重要人物。)
事实上,如今纯ASCII几乎无关紧要:没有人使用它。 ASCII 仅重要作为大多数8位编码(包括UTF-8)映射的公共子集:较低的128位Unicode代码点将1:1映射到数字值0-127(很多,许多编码。但纯ASCII(其中值128-255 未定义)不再处于活动状态。
作为旁注,Java 9有一个称为“紧凑字符串”的内部优化,其中只包含在Latin-1中可表示的字符的字符串每个字符使用一个字节而不是2.这种优化对于各种“非常有用”计算机说“像XML和类似的协议,其中大部分文本在ASCII范围内。但它对开发人员来说也是完全透明的,因为所有处理都是在String
类内部完成的,而且从外面看不到。
答案 1 :(得分:2)
Unicode是ASCII(和拉丁语1)的严格超集,至少关于字符 set 。与字节级别的实际编码无关。因此,不能有支持Unicode但不支持ASCII的语言/环境。上面的句子意味着,如果你只处理ASCII文本它就可以正常工作,因为如上所述,Unicode是ASCII的超集。
另外,要澄清一些误解:
“ASCII是1个字节,Unicode是2” - ASCII是7位代码,每个字符使用1个字节。因此字节和字符在ASCII中是相同的(这是不幸的,因为理想情况下,字节只是数据,文本是字符,但我离题了)。 Unicode是一个21位代码,用于定义代码点(数字)到字符的映射。如何表示这些数字取决于编码。 UTF-32是一种固定宽度编码,其中每个Unicode代码点都表示为32位代码单元。 UTF-16是Java使用的,每个代码点使用两个或四个字节(一个或两个代码单元)。但这是每个代码单元的16位,而不是每个代码点或实际字符(在Unicode意义上)。然后是UTF-8,它使用8位代码单元,并将代码点表示为一个,两个,三个或四个代码单元。
对于Java,至少该平台没有任何关于它是否仅支持ASCII或Unicode的说法。 Java总是使用Unicode,而char
代表UTF-16代码单元(可以是半字符),而不是代码点(可能是字符),因此有点误导性地命名。你可能指的是Unix在一些环境变量中结合语言,语言环境和首选系统编码的传统。也就是说,您可以拥有一个系统,其中首选编码指定遗留编码和盲目使用的可能存在问题的应用程序。这并不意味着您无法在此类系统上构建支持Unicode的应用程序。毕竟,iconv
必须以某种方式工作。