java编码问题详解

import java.io.UnsupportedEncodingException;
import java.util.Arrays;

/*
    编码: 字符变成字节数组

    解码: 字节数组变成字符串

    String --> byte[]  :   str.getBytes()
    byte[] --> String  :   new String(byte[])
 */

public class EncodeDemo {
    public static void main(String[] args) throws UnsupportedEncodingException {
        /*
            示例一:
                用相同的字符集编码和解码(UTF-8)
        */
        String str = "你好";
        byte[] bytes = str.getBytes("UTF-8");  // 用UTF-8字符集将“你好”转换成字节数组
        System.out.println(Arrays.toString(bytes));  // 打印编码后的字节数组: [-28, -67, -96, -27, -91, -67]

        str = new String(bytes, "UTF-8");  // 用UTF-8字符集将字节数组转换成字符串
        System.out.println(str);    // 你好

        /*
            示例二:
                用UTF-8编码,用UTF-8编码,再用ISO8859-1(拉丁字符集)解码,
                再用ISO8859-1编码,最后用UTF-8解码,可以再转换成相应的中文。
            注:ISO8859-1没有中文字符集,会将中文字符转换成不能识别的字符,然后可以再通过编码转换成原来的字节数组,
                再经过UTF-8解码成原有的中文。
        */

        bytes = str.getBytes("UTF-8");  // 用UTF-8字符集将“你好”转换成字节数组
        System.out.println(Arrays.toString(bytes));  // [-28, -67, -96, -27, -91, -67]
        str = new String(bytes, "ISO8859-1");  // ISO8859-1字符集会将一个字节转换为一个汉字,但由于此字符集中没有中文,所以会出现乱码的情况
        System.out.println(str);  // 打印结果:ä½ å¥½
        bytes = str.getBytes("ISO8859-1");  // 再将转换后的乱码重新编码,此时又会得到原来的字节数组
        str = new String(bytes, "UTF-8");  // 再经UTF-8解码以后,又会得到原来的汉字
        System.out.println(str);  // 打印:你好

        /*
            示例三:
                用GBK编码,用UTF-8解码
                两种字符集都有汉字编码
                但是GBK字符集一个汉字会转换成两个字节,而UTF-8字符集有可能是一个,有可能是两个,也有可能是三个
                那么,UTF-8是怎么确定该字符是由一个字节还是两个或者三个字节来组成的呢?
                它会根据字节数组的标头来判断:(转换成二进制后)
                    '\u0001' 到 '\u007F' 范围内的所有字符都是用单个字节表示的:
                            即第一个字节以0开头,那么该字符由一个字节组成
                    null 字符 '\u0000' 以及从 '\u0080' 到 '\u07FF' 的范围内的字符用两个字节表示:
                            即第一个字节以110开头,且下一个二进制数以10开头,那么该字符由两个字节组成
                    '\u0800' 到 '\uFFFF' 范围内的 char 值用三个字节表示:
                            即第一个字节以111开头,且后两个字节以10开头,那么该字符由三个字节组成
         */
        bytes = str.getBytes("GBK");  // GBK的汉字编码将一个字符转换为两个字节: [-60, -29, -70, -61]
        System.out.println(Arrays.toString(bytes));  // [-60, -29, -70, -61]
        str = new String(bytes, "UTF-8");
        System.out.println(str);  // 打印结果:���
        // 注:再将错误的字符用UTF-8编码后,并不能再得到原来的数组,因为在最初的解码时,UTF-8字符集会用一个相似的字符去代替不能正确解码的字符,
        // 所以再用UTF-8编码时并不能再得到原来的字节数组,继而用原有的字符集解码不能再得到原来的汉字
        bytes = str.getBytes("UTF-8");
        System.out.println(Arrays.toString(bytes));  // 打印:[-17, -65, -67, -17, -65, -67, -17, -65, -67]
        str = new String(bytes, "GBK");
        System.out.println(str);  // 打印: 锟斤拷锟�
    }
}
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值