Java UTF-8字符集在Windows Hotspot JVM 1.8.0_201中输出无效编码
抱歉,如果这是一个愚蠢的问题,我可能遗漏了一些基本的东西 我只是想用UTF-8编码一个字符串。按照最佳实践,我不假设默认字符集是UTF-8,因此我使用:Java UTF-8字符集在Windows Hotspot JVM 1.8.0_201中输出无效编码,java,unicode,utf-8,character-encoding,Java,Unicode,Utf 8,Character Encoding,抱歉,如果这是一个愚蠢的问题,我可能遗漏了一些基本的东西 我只是想用UTF-8编码一个字符串。按照最佳实践,我不假设默认字符集是UTF-8,因此我使用: "Ñ".getBytes(Charset.forName("UTF-8")) 根据,这应该是:0xc391 然而,我得到的是:0xc383e28098 我搞不懂这一点。无论我是否设置-Dfile.encoding=UTF-8,都会发生这种情况 奇怪的是,当我没有指定字符集(或使用charset.defaultCharset())时,使用了wi
"Ñ".getBytes(Charset.forName("UTF-8"))
根据,这应该是:0xc391
然而,我得到的是:0xc383e28098
我搞不懂这一点。无论我是否设置-Dfile.encoding=UTF-8
,都会发生这种情况
奇怪的是,当我没有指定字符集(或使用charset.defaultCharset()
)时,使用了windows-1252
编码,并且输出正确编码为UTF-8
更重要的是,当我通过IntelliJ而不是命令行运行代码时,UTF-8字符集实际上可以按预期工作。IntelliJ向类路径添加了许多不相关的库,因此我想其中一个库负责更正,但我希望它能在生产环境中工作
我的java-version
:
java version "1.8.0_201"
Java(TM) SE Runtime Environment (build 1.8.0_201-b09)
Java HotSpot(TM) Client VM (build 25.201-b09, mixed mode
你的代码没有问题。问题是编译器如何处理源代码 在代码中写入
“ñ”
并保存文件时,实际写入源文件的字节数是多少
看起来您已将源文件保存为UTF-8文件(这通常是一个不错的选择)。这意味着“ñ”
已作为UTF-8字节0xC3 0x91写入文件
如果您要在Windows以外的任何操作系统上编译它,系统的默认编码是UTF-8,那么它的构建和运行将完全符合您的预期
但在Windows上构建时,系统的默认字符集是Windows-1252,源文件中的这两个字节会得到不同的处理。编译器使用windows-1252解释这两个字节。不管代码在编辑器中是什么样子,编译器都会看到0xC3 0x91,并将每个字节视为一个字节。在windows-1252中,这些字节表示:
- 0xC3→ <代码>Ã()
- 0x91→ <代码>”()
“Ô
在运行时,当您使用UTF-8解码这两个字符串时,您将获得这两个字符的UTF-8字节序列:
→ 0xc3 0x83Ã
→ 0xe2 0x80 0x98”
正如您所猜测的,解决方案是告诉编译器您的源文件是UTF-8格式的,因此它会将字节0xc3 0x91解释为
ini
从byte[]
数组到0xc383e28098
十六进制值(进一步的Java代码、文件、十六进制编辑器等),您到底做了什么?字节数组在Java中有多长?@CarlosHeuberger为什么重要?我使用字符串文字,不必关心Java内部使用什么编码,它应该正确编码代码点。我还尝试输入字符串文字作为UTF-8字节数组,对其进行解码和重新编码,得到完全相同的结果。无论如何,我还是会尝试javac,但我不明白为什么它会有帮助…@RalfKleberhoff我只是将字节保存到一个文件中,然后用十六进制编辑器打开它,使用java.nio.file.Files.write(Path,byte[])
@CarlosHeuberger实际上,“ñ”
将被写成“\u00d1”
。(“\uc391”
是一个。)@CarlosHeuberger“\uc391”。getBytes(“UTF-8”)
不会产生那个输出。这简直是疯了。。。我可以发誓我试图直接使用字节数组和unicode文本(\u00d1),但没有成功。。。这对我来说更复杂,因为字符串文字只是我的一个例子-我在生产环境中看到了这种行为,其中通过电线接收的字符串被序列化。。。