java字符集

来源:互联网 发布:附加数据库失败 编辑:程序博客网 时间:2024/06/16 01:53

上面那行代码用到了 String 类的两个 api:


public byte[] getBytes()

public String(byte bytes[], Charset charset)


String 类说是 java 中使用最频繁,最常用的类,应该毫无争议吧。

但可能很多人并没仔细看过这个最熟悉类的java doc。

getBytes()的 java doc 如下描述:


Encodes this String into a sequence of bytes using the platform's default charset, storing the result into a new byte array.


意思是将该字符串使用平台默认字符集编码为一个字节序列并存储于返回的字节数组中。

而另一个构造函数 api 的 java doc 则说:


Constructs a new String by decoding the specified array of bytes using the specified charset


意思是使用指定的字符集解码字节数组来构造一个新的字符串。


通过 java doc 的说明,我们明白了这个构造函数指定的字符集是用于解码第一个传入参数字节数组的,而不是表达用这个字符集构造一个新的字符串(噢哦,不知道还有多少人被这个构造函数的签名欺骗误导了)。

那么上面的那行代码其实在表达什么意思呢,这里就呼之欲出了。

它将 msg 字符串采用平台默认编码为字节数组,再基于此字节数组通过 GBK 进行解码来构造一个新的字符串。

那么这个过程中发生了什么事情,字符串编码如我们所想从平台默认变为 GBK?如果这样想就真是很傻很天真了。

其实上面代码的执行过程,如果平台默认编码就是 GBK,那么这个代码就是创建了一个新字符串和原来 msg 相等,没副作用,干点无用功。

前文提及的接口乱码的问题正是因为,原先对方平台编码为 GBK,昨天突然改变为 UTF-8 后导致的乱码。



而程序原作者期待的转换编码过程其实完全没有必要,因为 java 中字符串的编码统一采用了 unicode 字符集。

而 String 对象的构造过程,就是将指定字符集编码的字节数组转换为 unicode 编码的字符串。

在 java 中说什么 GBK 编码的字符串,ISO-8859-1 编码的字符串都是无稽之谈。

那么我们经常在 web 开发中使用的一种转码方式,也是一段熟悉的代码可能又会使某些人陷入困惑了,如下:


new String(request.getParameter("xxxx").getBytes("iso-8859-1"),"utf-8")


上面这段代码在基于 tomcat 开发的一些 web 应用中进行转码有效,这又是为什么?

其实原因使从浏览器传入的请求参数一般默认使用的 utf-8 编码,而 tomcat 接收到请求后将参数采用默认的 iso-8859-1 解码生成了一个错误的字符串参数。

要恢复就得先把字符串恢复为原始字节数组,再通过 utf-8 来解码生成正确得字符串,所以才有如上写法。

而如上写法,对于不明白浑浑噩噩的程序员,就误认为将 iso-8859-1 的字符串转换为了 utf-8 格式的字符串。(这也没什么好羞耻的,我也这样以为了好些年:)




数字类型,如1、2、3等。

字符类型,如a、b、c等。
特殊字符,如#、$、%、^、&等
不可见字符,如\n(换行符)、\r(回车符)、\t(Tab字符)等。
【注意】\n(换行符)和\r(回车符)在windows系统中没有什么区别,都可以当做回车符。但是在linux系统中则是两种效果。在linux系统中,\n表示换到下一行,却不会回到行首;而\r表示光标回到行首,但仍然在本行。

字符的编码-Unicode编码和Unicode码:

在 JVM中,字符是使用 Unicode编码的。Unicode编码指的是UCS-2编码方式,即直接用两个字节存入字符的Unicode码。Unicode是一个很大的集合,将世界上所有的符号都纳入其中,每一个符号都给予一个独一无二的编码。需要注意的是,Unicode只是一个符号集,它只规定了符号的二进制代码,却没有规定这个二进制代码应该如何存储。基本多文种平面是Unicode中的一个编码区段。编码从U+0000至U+FFFF。常用汉字在此区间对应。常用字占用2个字节,在多文种平面区。冷僻字占用4个字节,在其它平面。所以,冷僻的汉子无法在Java中使用。

字符的转码:

因为一个字符可以使用多种编码方式进行表示,所以在不同的编码方式直接可以进行自由的转换。如下面的小例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
importjava.io.UnsupportedEncodingException;
public classTest1
{
    publicstatic voidmain(String[]args)throws UnsupportedEncodingException
    {
        Stringweb ="金丝燕网";  
        byte[]bytegbk =web.getBytes("gbk");
        Stringresult =new String(bytegbk,"gbk");  
        System.out.println(result);  
          
        bytegbk= result.getBytes("utf-8");
        result= newString(bytegbk,"utf-8");  
        System.err.println(result);  
    }
}

转换字符集----java


原创粉丝点击