【字符編碼】Java編碼格式探祕

1、前言java

  在分析Comparable和Comparator的時候,分析到了String類的compareTo方法,String底層是用char[]數組來存放元素,在比較的時候是比較的兩個字符串的字符,字符用char來存儲,此時,忽然想到,Java裏面的char能夠存放中文嗎?後來發現是能夠的,而且由此也引出了Java中字符的編碼格式問題。數組

2、Java存儲格式app

  在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-一、unicode、utf-8編碼都是不相同的,至於各個編碼的含義,咱們這裏不給出解釋,下一篇會給出答案。那麼,在JVM中,字符'張'是按照哪一種編碼格式進行存儲的呢?下面開始咱們的分析。spa

3、探祕思路code

 1. 查看.class文件常量池的存儲格式orm

  測試代碼以下  blog

public class Test {
    public static void main(String[] args) {
        String str = "張";        
    }
}

  使用javap -verbose Test.class進行反編譯,發現常量池狀況以下:utf-8

  再使用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中也是兩個字節,故能夠存放。

4、總結

  通過上面的分析,咱們知道:

  1. 字符在class文件中是以utf-8格式進行編碼的,而在JVM運行時是採用utf-16格式進行編碼的。

  2. char類型是兩個字節,能夠用來存放中文。

  在這次調用的過程當中又查閱了好多關於字符方面的資料,受益不淺,而且發現特別有意思,接下來會進行分享,因此特此預告下一篇將會進一步來介紹編碼以及編碼在Java中的問題。敬請期待,也謝謝各位園友的觀看~

相關文章
相關標籤/搜索