MacOS和Windows中相同字符的不同代码点

时间:2018-10-31 20:02:45

标签: java string unicode utf-8 windows-1252

我有一小段代码,我正在其中检查字符Ü的代码点。

Locale lc = Locale.getDefault();
System.out.println(lc.toString());
System.out.println(Charset.defaultCharset());
System.out.println(System.getProperty("file.encoding"));
String inUnicode = "\u00dc";
String glyph = "Ü";
System.out.println("inUnicode " + inUnicode + " code point " + inUnicode.codePointAt(0));
System.out.println("glyph " + glyph + " code point " + glyph.codePointAt(0));

在MacOS x和Windows 10上运行此代码时,我得到的codepoint值不同,请参见下面的输出。

在MacOS上的输出

en_US
UTF-8
UTF-8
inUnicode Ü code point 220
glyph Ü code point 220

Windows上的输出

en_US
windows-1252
Cp1252
in unicode Ü code point 220
glyph ?? code point 195

我在https://en.wikipedia.org/wiki/Windows-1252#Character_set处检查了Windows-1252的代码页,这里Ü的代码点是220。 对于String glyph = "Ü";,为什么在Windows上将代码点设为195?根据我的理解,glyph应该已经正确呈现,并且代码点应该已经220,因为它是在Windows-1252中定义的。

如果我将String glyph = "Ü";替换为String glyph = new String("Ü".getBytes(), Charset.forName("UTF-8"));,则glyph会正确呈现,并且代码点值为220。 不管语言环境和字符集如何,这是否是在任何操作系统上标准化String行为的正确而有效的方法?

1 个答案:

答案 0 :(得分:0)

195是十六进制的0xC3。

在UTF-8中,Ü被编码为字节0xC3 0x9C

System.getProperty("file.encoding")表示Windows上的默认文件编码不是UTF-8,但显然您的Java文件实际上是用UTF-8编码的。 println()正在输出glyph ??(注2 ?,表示存在2个char),并且您能够使用UTF解码原始字符串字节这一事实-8 Charset,证明了这一点。

glyph应该只有一个char,其值为0x00DC,而不是2个char,其值为0x00C3 0x009CgetCodepointAt(0)在Windows上返回0x00C3(195),因为您的Java文件使用UTF-8编码,但正在加载,就像使用Windows-1252编码一样,因此2字节{{1} }解码为字符0xC3 0x9C,而不是字符0x00C3 0x009C

运行Java时,您需要指定实际的文件编码,例如:

0x00DC