用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

时间: 2024-10-10 14:56:51

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

String(byte[] bytes, String charsetName)

String str = new String("时之沙"); byte bytes[] = str.getBytes("GBK"); byte byte2[] = str.getBytes("ISO-8859-1"); String str_gbk = new String(bytes, "GBK"); System.out.println("str_gbk:" + str_gbk); String st

java.lang.String类

复制下来的java.lang.String源码.在此基础上添加自己的注释,偷懒了,用来加深印象吧.英语不好,没有翻译,不理解的方法直接百度的.然后按照自己的理解描述. /* * @(#)String.java 1.205 09/02/26 * * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. */

java.lang.String 类源码解读

String类定义实现了java.io.Serializable, Comparable<String>, CharSequence 三个接口:并且为final修饰. public final class String defined String由char[]数组实现 /** The value is used for character storage. */ private final char value[]; /** Cache the hash code for the strin

Java之String类常用API

目录 Java之String类常用API char chatAt(int index) int length() char[] toCharArray() String(char value[]) String(char value[], int offset, int count) int compareTo(String anotherString) String concat(String str) boolean contains(CharSequence s) boolean ends

【java】String类的基本方法

Java的String类基本方法 一.构造函数 函数 返回值 作用 String(byte[] bytes) String 通过byte数组构造字符串对象 String(char[] chars) String 通过char数组构造字符串对象 String(String string) String 拷贝一个值为string的字符串对象 String(StringBuffer buffer) String 通过StringBuffer构造字符串对象 二.String类的基本方法 函数 返回值 作

java常见类之String类

1.字符串概述 字符串:就是由多个字符组成的一串字符,也可以看成是字符数组. String类代表字符串,java程序中的字符串字面值,如"abc"等都作为此类的实例实现. 字符串是常量,一旦被赋值,就不能被改变. 2.String的构造方法 public String() 空构造 public String(byte[] bytes) 把字节数组转换成字符串 public String(byte[] bytes,int offset,int length) 把字节数组的指定索引长度的字

Java String 类解析

I.构造函数: public String() {} 默认构造函数 public String(String original) {} 使用原有字符串构造  public String(char value[]) {} 使用字符型数组构造 public String(char value[], int offset, int count) {} 使用给定的字符数组构造 offset指明从value哪个字符开始: count指明截取字符数组的长度: 源码使用Arrays.copyOfRange()

JAVA API(一)String类和StringBuffer类

1.String类和StringBuffer类 在程序中经常会用到字符串,所谓的字符串就是指一连串的字符,它是由多个单个字符连接而成的.字符串中可以包含任意字符,这些字符必须包含在一对双引号""之内,如"abc".在Java中定义了String和StringBuffer类来封装字符串,并提供了一系列操作字符串的方法,它们都位于java.lang包中,因此不需要导包就可以直接使用.下面将对String类和StringBuffer类详细讲解. 1.1String类的初始

Java——常用类(String)

[常用类] <1>字符串相关类(String.StringBuffer) <2>基本数据类型包装类 <3>Math类 <4>File类 <5>枚举类 [String类] <1>java.lang.String类代表不可变的字符序列. <2>String类的常见构造方法: String(String original) //创建一个String对象为original的拷贝 String(char[] value) //用一个