从编译到运行时,Java字符串编码如何真正工作
2022-09-02 08:57:57
我最近意识到我并不完全了解Java的字符串编码过程。
请考虑以下代码:
public class Main
{
public static void main(String[] args)
{
System.out.println(java.nio.charset.Charset.defaultCharset().name());
System.out.println("ack char: ^"); /* where ^ = 0x06, the ack char */
}
}
由于 windows-1252 和 ISO-8859-1 之间的控制字符解释不同,因此我选择了 char 进行测试。ack
我现在使用不同的文件编码,UTF-8,windows-1252和ISO-8859-1编译它。两者编译为完全相同的东西,由 验证的每字节字节。md5sum
然后我运行该程序:
$ java Main | hexdump -C
00000000 55 54 46 2d 38 0a 61 63 6b 20 63 68 61 72 3a 20 |UTF-8.ack char: |
00000010 06 0a |..|
00000012
$ java -Dfile.encoding=iso-8859-1 Main | hexdump -C
00000000 49 53 4f 2d 38 38 35 39 2d 31 0a 61 63 6b 20 63 |ISO-8859-1.ack c|
00000010 68 61 72 3a 20 06 0a |har: ..|
00000017
$ java -Dfile.encoding=windows-1252 Main | hexdump -C
00000000 77 69 6e 64 6f 77 73 2d 31 32 35 32 0a 61 63 6b |windows-1252.ack|
00000010 20 63 68 61 72 3a 20 06 0a | char: ..|
00000019
无论使用哪种编码,它都会正确输出 。0x06
好的,它仍然输出相同的,这将被windows-1252代码页解释为可打印的[ACK]char。0x06
这让我想到了几个问题:
- 正在编译的 Java 文件的代码页/字符集是否应与编译它的系统的缺省字符集相同?这两者总是同义词吗?
- 编译的表示形式似乎不依赖于编译时字符集,事实果真如此吗?
- 这是否意味着如果 Java 文件中的字符串不对当前字符集/区域设置使用标准字符,则在运行时可能会有不同的解释?
- 关于Java中的字符串和字符编码,我还需要了解哪些内容?