1700442881
编写高质量代码:改善Java程序的151个建议 建议58:强烈建议使用UTF编码
1700442882
1700442883
Java的乱码问题由来已久,有点经验的开发人员肯定都遇到过乱码问题,有时是从Web上接收的乱码,有时是从数据库中读取的乱码,有时是在外部接口中接收到的乱码文件,这些都让我们困惑不已,甚至是痛苦不堪,看如下代码:
1700442884
1700442885
public static void main(String[]args)throws Exception{
1700442886
1700442887
String str=“汉字”;
1700442888
1700442889
//读取字节
1700442890
1700442891
byte[]b=str.getBytes(“UTF-8”);
1700442892
1700442893
//重新生成一个新的字符串
1700442894
1700442895
System.out.println(new String(b));
1700442896
1700442897
}
1700442898
1700442899
Java文件是通过IDE工具默认创建的,编码格式是GBK,大家想想看上面的输出结果会是什么?可能是乱码吧?两个编码格式不相同。我们暂不公布结果,先解释一下Java中的编码规则。Java程序涉及的编码包括两部分:
1700442900
1700442901
(1)Java文件编码
1700442902
1700442903
如果我们使用记事本创建一个.java后缀的文件,则文件的编码格式就是操作系统默认的格式。如果是使用IDE工具创建的,如Eclipse,则依赖于IDE的设置,Eclipse默认是操作系统编码(Windows一般为GBK)。
1700442904
1700442905
(2)Class文件编码
1700442906
1700442907
通过javac命令生成的后缀名为.class的文件是UTF-8编码的UNICODE文件,这在任何操作系统上都是一样的,只要是class文件就会是UNICODE格式。需要说明的是,UTF是UNICODE的存储和传输格式,它是为了解决UNICODE的高位占用冗余空间而产生的,使用UTF编码就标志着字符集使用的是UNICODE。
1700442908
1700442909
再回到我们的例子上,getBytes方法会根据指定的字符集提取出字节数组(这里按照UNICODE格式来提取),然后程序又通过newString(byte[]bytes)重新生成一个字符串。来看看String这个构造函数:通过操作系统默认的字符集解码指定的byte数组,构造一个新的String。结果已经很清楚了,如果操作系统是UTF-8编码的话,输出就是正确的,如果不是,则会是乱码。由于这里使用的是默认编码GBK,那么输出的结果也就是乱码了。我们再详细分解一下运行步骤:
1700442910
1700442911
步骤1 创建Client.java文件。
1700442912
1700442913
该文件的默认编码GBK(如果使用Eclipse,则可以在属性查看到)。
1700442914
1700442915
步骤2 编写代码(如上)。
1700442916
1700442917
步骤3 保存,并使用javac编译。
1700442918
1700442919
注意我们没有使用“javac-encoding GBK Client.java”显式声明Java的编码格式,javac会自动按照操作系统的编码(GBK)读取Client.java文件,然后将其编译成.class文件。
1700442920
1700442921
步骤4 生成.class文件。
1700442922
1700442923
编译结束,生成.class文件,并保存到硬盘上。此时.class文件使用的是UTF-8格式编码的UNICODE字符集,可以通过javap命令阅读class文件。其中“汉字”变量也已经由GBK编码转变成UNICODE格式了。
1700442924
1700442925
步骤5 运行main方法,提取“汉字”的字节数组。
1700442926
1700442927
“汉字”原本是按照UTF-8格式保存的,要再提取出来当然没有任何问题了。
1700442928
1700442929
步骤6 重组字符串。
[
上一页 ]
[ :1.70044288e+09 ]
[
下一页 ]