• 用java String类的getBytes(String charsetName)和String(byte[] bytes, String charsetName)解决乱码问题


    Java中String的数据是如何存储的,查看源代码就可以知道,String的数据是存储在char[] value这样一个成员变量中的,char类型的大小在java中是2个字节 
    我们还知道,现在普遍使用的unicode版本是UCS-2,就是使用2个字节表示一个字符的unicode版本,这就对上了,java使用的就是UCS-2标准,所以,String中的value中存储的都是一个个数字

    比如’你’的unicode编码是4f60,看下面的测试代码

    char c = '你';
    System.out.println(Integer.toHexString(c));
    System.out.println(Integer.valueOf(c));
    System.out.println(c);

    结果是: 
    4f60 
    20320 

    所以呢,现在我们知道了String内部其实存储的是未经任何编码的unicode编码,就是那个对应字符的编码,然后再看我们这两个方法:

    getBytes(charsetname) 
    意思是根据这个编码来获取字节数组 
    这又是什么意思呢? 
    就是说将内存中的unicode编码转换为charsetname格式所对应的字节数组 
    比如’你’,转换为utf-8是三个字接,所以得到的字节数组就是三个字节的 
    即[e4 bd a0]

    然后String(bytes,charsetname)呢

    意思就是将bytes这个字节数组按照charsetname解释,组装为一个String保存起来 
    例如上面那个字节数组[e4 bd a0],按照utf-8解释的话,存储起来就是”你”这个字符串,如果按照其他编码解释,则不会解释为”你”

    说个其他的,为什么在servlet中处理参数一般都需要这么一句了来控制编码:

    String str = new String(param.getBytes(“ISO-8859-1”),”UTF-8”);

    其实这很好理解,浏览器传过来的字节数据是UTF-8编码的,然后web容器默认这个字节数据是ISO-8859-1编码的,所以使用ISO-8859-1把这个字节数据转换变成了String存储起来,相当于是进行了下面这个操作:

    String s = new String(UTF8Bytes,”ISO-8859-1”);

    注意这个编码是单字节的,也就是将每一个字节都转换成了unicode编码,幸好是这样,使我们有机会将这个String再转换成和原来一模一样的字节数组,所以才有了我们平时用的最多的那一句编码处理的代码

    最后,想再说一下,对编码这块不了解的原因,是我们理解错误,我们必须知道的是:

    java内部存储字符串使用的unicode编码 
    我们通常会听到有人说:“我需要将String由ISO-8859-1转换为GBK编码”,这又是怎么回事呢?实际上,我们并不是要“将 一个由ISO-8859-1编码的String转换为GBK编码的String”,反复说明的是,JAVA中的String都是unicode编码的,所以不存在“ISO- 8859-1编码的String”或“GBK编码的String”这样的说法。而需要转换的唯一的原因是String进行了错误的编码。我们经常会碰到由ISO-8859- 1转换为诸如GBK/UTF-8等等这样的需求。所谓的转换过程是:String –> byte[] –>String

  • 相关阅读:
    MyEclipse修改默认的workspace路径
    对象池化技术 org.apache.commons.pool
    Java 简单工厂模式
    组装品入力
    引当日数和JAN日数的意思
    材料构成模块的做法
    在库移动和在库振替的意思
    组装品的特殊式样
    设计的尝试数据库・数据的更新
    定时器(Timer)文章收集转载(小雨论坛)
  • 原文地址:https://www.cnblogs.com/Seachal/p/5769177.html
Copyright © 2020-2023  润新知