我有一小段代码,我正在其中检查字符Ü
的代码点。
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行为的正确而有效的方法?
答案 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 0x009C
。 getCodepointAt(0)
在Windows上返回0x00C3
(195),因为您的Java文件使用UTF-8编码,但正在加载,就像使用Windows-1252编码一样,因此2字节{{1} }解码为字符0xC3 0x9C
,而不是字符0x00C3 0x009C
。
运行Java时,您需要指定实际的文件编码,例如:
0x00DC