Java中字符串的编码转换

说明: 在JVM内部,字符串在java中统一用unicode表示。无论源文件是用什么编码,都会先用相应地编码方式解析成字符串,再将字符串转换为unicode格式的字节数组,作为内部存储。因此,不论源码文件是什么格式,同样的字符串,最后得到的unicode字节数组是完全一致的。

在程序未运行时,字符串以原始编码的字节数组存储在系统磁盘中;在程序运行时,字符串会被转化为unicode字符数组存储在JVM内存中(原始字节数组-->原始编码方式解码-->字符串-->Unicode编码-->Unicode字节数组)

其他
      1、ASII码:字符串中的每个字符用一个字节表示。每个字符实际上只使用了7位,从00h-7Fh。只能表达128个字符。不能代表汉字。
      2、Unicode码:字符串中的每个字符用两个字节表示。

编码:字符串--->字节数组
解码:字节数组--->字符串

字符串GBK转UTF-8过程

1、字符串-->经过GBK编码-->GBK字节数组         (若直接使用UTF8解码GBK字节数组,将会乱码)
        
2、GBK字节数组-->经过GBK解码-->得到字符串-->使用unicode编码-->unicode字节数组   (将GBK字节数组转化为Unicode字节数组)
        
3、unicode字节数组-->使用unicode解码-->得到字符串-->使用UTF8编码-->UTF8字节数组   (再将unicode字节数组转化为UTF8字节数组)
        
4、UTF8字节数组-->使用UTF8解码-->得到字符串  (解码UTF8字节数组)

测试

public class TestExcode {

public static void main(String[] args) throws IOException {
    testStrEncode1();
    //testStrEncode2();
    //testStrEncode3();
}

public static void testStrEncode1() throws UnsupportedEncodingException {
    
    String a = "你好";
    //程序未运行时,原始编码为UTF-8,底层存储是UTF-8编码后的字节数组,我们看到的信息是通过UTF-8解码之后显示的。
    
    //程序运行时,a被转化为unicode字节数组存储在JVM内存中
    //使用ISO-8859-1编码时,会先将unicode字节数组解码得到字符串,再用ISO-8859-1编码字符串得到字节数组
    byte[] b = a.getBytes("ISO-8859-1");   //ISO-8859-1无法编码中文,新的字节数组已经不同于原始字节数组
    byte[] c = a.getBytes("UTF-8");        //解码和编码均为UTF-8,新的字节数组和原始字节数组仍然相同
    
    //使用UTF-8解码刚才ISO-8859-1编码的字节数组
    //解码得到的字符串与原始字符串不同(乱码)
    String result = new String(b,"UTF-8");
    String result1 = new String(c,"UTF-8");
    
    System.out.println(result);     //输出'??' ,因为ISO-8859-1无法编码中文 
    System.out.println(result1);    //输出'你好'
}

public static void testStrEncode2() throws UnsupportedEncodingException {
    
    String a = "你好";
    //原始编码为UTF-8,底层存储是UTF-8编码后的字节数组,我们看到的信息是UTF-8解码之后显示的。
    
    //程序运行时,a被转化为unicode字节数组存储在JVM内存中
    //使用ISO-8859-1编码时,会先将unicode字节数组解码得到字符串,再用ISO-8859-1编码字符串得到新的字节数组
    byte[] b = a.getBytes("ISO-8859-1"); //ISO-8859-1编码可以编码"你好",但新的字节数组和原始字节数组已经不同了
    byte[] c = a.getBytes("UTF-8");      //UTF-8可以编码"你好",新的字节数组和原始字节数组仍然相同
    
    //使用UTF-8解码刚才ISO-8859-1编码的字节数组
    //解码得到的字符串与原始字符串不同
    String result = new String(b,"UTF-8");  
    String result1 = new String(c,"ISO-8859-1");
    
    System.out.println(result);   //输出'你好'
    System.out.println(result1);  //输出'你好'

    //分析:对比testStrEncode1和testStrEncode2
    //将"你好"替换为"你好"后,result输出'你好',result1输出"你好",
    //这表示"你好"用ISO-8859-1编码后的字节数组和"你好"用UTF-8编码后的字节数组相同
}
public static void testStrEncode3() throws UnsupportedEncodingException {
    //GBK、ISO-8859-1、UTF-8、Unicode等编码方式之间不存在包含关系
    //GBK和UTF-8都支持中文和英文,但是UTF-8不仅支持中文,还支持其他国家的语言,应用更广泛

    String fileName = "我最亲爱的祖国";

    //GBK编码,GBK解码。正常输出。
    System.out.println(new String(fileName.getBytes("GBK"),"GBK"));

    //GBK编码,ISO-8859-1解码。乱码
    System.out.println(new String(fileName.getBytes("GBK"),"ISO-8859-1"));

    //GBK编码,使用默认UTF-8解码。乱码
    System.out.println(new String(fileName.getBytes("GBK")));

    //ISO-8859-1编码,ISO-8859-1解码。ISO-8859-1编码不了中文,编码失败,会乱码。
    System.out.println(new String(fileName.getBytes("ISO-8859-1"),"ISO-8859-1"));
    
    //ISO-8859-1编码,使用默认UTF-8解码。乱码
    System.out.println(new String(fileName.getBytes("ISO-8859-1")));

    //ISO-8859-1编码,GBK解码。乱码
    System.out.println(new String(fileName.getBytes("ISO-8859-1"),"GBK"));

    //UTF-8编码,使用默认UTF-8解码。正常输出
    System.out.println(new String(fileName.getBytes("UTF-8")));
    
    //UTF-8编码,ISO-8859-1解码。乱码
    System.out.println(new String(fileName.getBytes("UTF-8"),"ISO-8859-1"));

    //UTF-8编码,GBK解码。乱码
    System.out.println(new String(fileName.getBytes("UTF-8"),"GBK"));

}
}

你可能感兴趣的:(Java)