java 中的字符编码转换

参考解答

首先明确一点:java中存储一个字符,都是利用了unicode字符编码, 总是占用两个字节(想想char)

例如:

String s1 = "h"; // 在java中实际存储为 \u0068

中文也同样是两个字节:

String s2 = "中"; // 在java中实际存储为 \u4e2d

但java对外输出(如文件、网络),会采用其它的字符编码,例如ISO-8859-1GBKUTF-8

  • ISO-8859-1 只占一个字节,只能表示英文字符
  • GBK可以表示中英文字符,英文字符占一个字节,中文字符占两个字节
  • UTF-8可以表示中英文(全球语言)字符,英文字符占一个字节,中文字符占三个字节

可以使用getBytes("字符编码")将java中的 unicode 字符按不同的字符编码转换为字节,下面列出了几种转换结果:

byte[] out;
out = "h".getBytes("ISO-8859-1");  // {0x68}
out = "h".getBytes("GBK");         // {0x68}
out = "中".getBytes("GBK");        // {0xd6, 0xd0}
out = "h".getBytes("UTF-8");       // {0x68}
out = "中".getBytes("UTF-8");      // {0xe4, 0xb8, 0xad}

可以使用new String(byte[], "字符编码") 将字节按某种编码还原成java 的 unicode:

String str;
str = new String(new byte[]{0x68},"ISO-8859-1"); // 还原为\u0068
str = new String(new byte[]{(byte)0xd6, (byte)0xd0},"GBK");// 还原为\u4e2d
str = new String(new byte[]{(byte)0xe4, (byte)0xb8, (byte)0xad},"UTF-8"); // 还原为\u4e2d

思考下面的例子,会怎么样?

String str = new String("中".getBytes("GBK"),"ISO-8859-1");

分析:

  • "中".getBytes("GBK") 结果转换为字节数组:{0xd6, 0xd0}
  • 再将{0xd6, 0xd0} 按"ISO-8859-1"还原为unicode:\u00d6 \u00d0, 直接打印的效果是 ÖÐ
  • 这就是web开发中著名的乱码问题

如何解决呢?再做一次对称的操作即可:

String r = new String("ÖÐ".getBytes("ISO-8859-1"),"GBK"); // 还原成\u4e2

其实就是:

String str = "ÖÐ"; // 上一步的乱码,即\u00d6 \u00d0
byte[] b = str.getBytes("ISO-8859-1"); //{0xd6, 0xd0}
String r = new String(b,"GBK"); // 还原成\u4e2d

results matching ""

    No results matching ""