Java中char类型占用多少个字节

先区分unicode和UTF。

unicode :Unicode(统一码、万国码、单一码)是计算机科学领域里的一项业界标准,包括字符集、编码方案等。Unicode 是为了解决传统的字符编码方案的局限而产生的,它为每种语言中的每个字符设定了统一并且唯一的二进制编码,以满足跨语言、跨平台进行文本转换、处理的要求。统一的字符编号,仅仅提供字符与编号间映射。符号数量在不断增加,已超百万。详细:[https://zh.wikipedia.org/zh-cn/Unicode]
UTF :unicode转换格式 (unicode transformation format) 。定义unicode中编号的编码方式。utf8和utf16便是其中两种实现方式。其中utf8为变长表示,长度可能时1~6个字节;utf16为变长表示,长度可能是2或4个字节。详细:UTF8 [https://zh.wikipedia.org/zh-cn/UTF-8] UTF16 [https://zh.wikipedia.org/zh-cn/UTF-16]

接着,要分清内码(internal encoding)和外码(external encoding)。

内码 :某种语言运行时,其char和string在内存中的编码方式。
外码 :除了内码,皆是外码。
要注意的是,源代码编译产生的目标代码文件(可执行文件或class文件)中的编码方式属于外码。

先看一下内码
JVM中内码采用UTF16。早期,UTF16采用固定长度2字节的方式编码,两个字节可以表示65536种符号(其实真正能表示要比这个少),足以表示当时unicode中所有字符。但是随着unicode中字符的增加,2个字节无法表示所有的字符,UTF16采用了2字节或4字节的方式来完成编码。Java为应对这种情况,考虑到向前兼容的要求,Java用一对char来表示那些需要4字节的字符。所以,java中的char是占用两个字节,只不过有些字符需要两个char来表示。
详细:
[https://docs.oracle.com/javase/tutorial/i18n/text/unicode.html]
[http://www.zhihu.com/question/27562173]

外码
Java的class文件采用UTF8来存储字符,也就是说,class中字符占1~6个字节。
Java序列化时,字符也采用UTF8编码,占1~6个字符。

public class BytesOfChar {
    public static byte[] getBytesUTF8 (char  c ) {
        Charset cs = Charset.forName("utf-8");
        CharBuffer cb = CharBuffer.allocate (1);
        cb.put (c);
        cb.flip ();
        ByteBuffer bb = cs.encode (cb);
        return bb.array();
        }
    public static byte[] getBytesGBK (char c) {
        Charset cs = Charset.forName("GBK");
        CharBuffer cb = CharBuffer.allocate (1);
        cb.put(c);
        cb.flip ();
        ByteBuffer bb = cs.encode (cb);
        return bb.array();
        }
   public static void main(String[] args) throws UnsupportedEncodingException {
       char c='a';
       char cc='中';
       String str="a";
       String strr="中";
       String s="a";
       System.out.println("编码为UTF8:");
       System.out.println("char值为英文字符所占字节长度:"+getBytesUTF8(c).length);
       System.out.println("char值为中文字符所占字节长度:"+getBytesUTF8(cc).length);
       System.out.println("编码为GBK(默认编码):");
       System.out.println("char值为英文字符所占字节长度:"+getBytesGBK(c).length);
       System.out.println("char值为中文字符所占字节长度:"+getBytesGBK(cc).length);
       System.out.println("-------------------------------");
       System.out.println("编码为UTF8");
       System.out.println("String为英文字母所占字节长度:"+str.getBytes("utf-8").length);
       System.out.println("String为中文字母所占字节长度:"+strr.getBytes("utf-8").length);
       System.out.println("编码为GBK:");
       System.out.println("String为英文字母所占字节长度:"+str.getBytes("GBK").length);
       System.out.println("String为中文字母所占字节长度:"+strr.getBytes("GBK").length);
       System.out.println("String为英文字母(全角)所占字节长度:"+s.getBytes("GBK").length);

}
}
运行结果:
编码为UTF8:
char值为英文字符所占字节长度:1
char值为中文字符所占字节长度:3
编码为GBK(默认编码):
char值为英文字符所占字节长度:2
char值为中文字符所占字节长度:2
-------------------------------
编码为UTF8
String为英文字母所占字节长度:1
String为中文字母所占字节长度:3
编码为GBK:
String为英文字母所占字节长度:1
String为中文字母所占字节长度:2
String为英文字母(全角)所占字节长度:2

总结:

  1. java中内码(运行内存)中的char使用UTF16的方式编码,一个char占用两个字节,但是某些字符需要两个char来表示。所以,一个字符会占用2个或4个字节。
  2. java中外码中char使用UTF8的方式编码,一个字符占用1~6个字节。
  3. .UTF16编码中,英文字符占两个字节;绝大多数汉字(尤其是常用汉字)占用两个字节,个别汉字(在后期加入unicode编码的汉字,一般是极少用到的生僻字)占用四个字节。
  4. UTF8编码中,英文字符占用一个字节;绝大多数汉字占用三个字节,个别汉字占用四个字节。
  5. 编码为GBK(默认编码):char值为英文字符,中文字符所占字节长度:2

你可能感兴趣的:(java基础)