Java中字符编码格式详解
一、前言
在分析comparable和comparator的时候,分析到了string类的compareto方法,string底层是用char[]数组来存放元素,在比较的时候是比较的两个字符串的字符,字符用char来存储,此时,突然想到,java里面的char可以存放中文吗?后来发现是可以的,并且由此也引出了java中字符的编码格式问题。
二、java存储格式
在java中,如下代码获取了字符'张'的各种编码格式。
import java.io.unsupportedencodingexception; public class test { public static string getcode(string content, string format) throws unsupportedencodingexception { byte[] bytes = content.getbytes(format); stringbuffer sb = new stringbuffer(); for (int i = 0; i < bytes.length; i++) { sb.append(integer.tohexstring(bytes[i] & 0xff).touppercase() + " "); } return sb.tostring(); } public static void main(string[] args) throws unsupportedencodingexception { system.out.println("gbk : " + getcode("张", "gbk")); system.out.println("gb2312 : " + getcode("张", "gb2312")); system.out.println("iso-8859-1 : " + getcode("张", "iso-8859-1")); system.out.println("unicode : " + getcode("张", "unicode")); system.out.println("utf-16 : " + getcode("张", "utf-16")); system.out.println("utf-8 : " + getcode("张", "utf-8")); } }
运行结果:
gbk : d5 c5 gb2312 : d5 c5 iso-8859-1 : 3f unicode : fe ff 5f 20 utf-16 : fe ff 5f 20 utf-8 : e5 bc a0
说明:从结果我们可以知道,字符'张'的gbk与gb2312编码是相同的,unicode与utf-16编码时相同的,但是其iso-8859-1、unicode、utf-8编码都是不相同的。那么,在jvm中,字符'张'是按照哪种编码格式进行存储的呢?下面开始我们的分析。
三、探秘思路
1. 查看.class文件常量池的存储格式
测试代码如下
public class test { public static void main(string[] args) { string str = "张"; } }
使用javap -verbose test.class进行反编译,发现常量池情况如下:
再使用winhex打开class文件,发现字符'张'在常量池的存储如下
说明:上面两张可以在class文件中是以utf-8的格式存储的。
但是在运行时是否是utf-8格式呢?继续我们的探秘之旅。
2. 在程序中一探究竟
使用如下代码
public class test { public static void main(string[] args) { string str = "张"; system.out.println(integer.tohexstring(str.codepointat(0)).touppercase()); } }
运行结果:
5f20
说明:根据结果我们知道在运行时jvm是使用的utf-16格式进行存储,utf-16一般是使用2个字节进行存储,如果遇到两个字节无法表示的字符则会使用4个字节表示。之后会另外有篇幅进行介绍,并且我们查看character类源码时,会发现就是使用的utf-16进行编码的,从两面都找到了我们想要的答案。
3. char类型可以存放中文吗?
根据上面的探索我们已经知道了java的class文件中字符是以utf-8进行编码的,在jvm运行时则是以utf-16进行编码存储的。而字符'张'可以用两个字节来表示,而char在java中也是两个字节,故可以存放。
四、总结
经过上面的分析,我们知道:
1. 字符在class文件中是以utf-8格式进行编码的,而在jvm运行时是采用utf-16格式进行编码的。
2. char类型是两个字节,可以用来存放中文。
在此次调用的过程中又查阅了好多关于字符方面的资料,受益匪浅,并且发现特别有意思,接下来会进行分享,所以特此预告下一篇将会进一步来介绍编码以及编码在java中的问题。敬请期待
上一篇: asp.net GridView导出到Excel代码
下一篇: 图片验证码概述及实现步骤