Java字符編碼—Unicode與UTF-8的區(qū)別

Unicode字符集

Unicode,是計(jì)算機(jī)科學(xué)領(lǐng)域里的一項(xiàng)業(yè)界標(biāo)準(zhǔn)。為每種語言中的每個(gè)字符設(shè)定了統(tǒng)一并且唯一的整數(shù)值,把這個(gè)數(shù)值稱為碼點(diǎn)(Code Point)。
但是它并不規(guī)定計(jì)算機(jī)如何存儲(chǔ)和傳輸這個(gè)數(shù)值(以多少個(gè)字節(jié)存儲(chǔ),是定長(zhǎng)還是變長(zhǎng),Unicode沒有字節(jié)長(zhǎng)度的概念)。

Unicode 定義了一個(gè)碼點(diǎn)空間包含1,114,112個(gè)碼點(diǎn),范圍從0到0x10FFFF,也就是說,它僅僅是一個(gè)字符映射集。其中 0x0000 ~ 0xFFFF 的字符表示常用字符集,稱 BMP字符,0x10000 ~ 0x10FFFF 字符叫增補(bǔ)字符。

Unicode 目前規(guī)劃的總空間是17個(gè)平面(平面0至16),0x0000 至 0x10FFFF,每個(gè)平面有 65536 個(gè)碼點(diǎn)。
例如,"AB中國"這個(gè)字符串,對(duì)應(yīng)的 Unicode 編碼為:

A  -> \u0041
B  -> \u0042
中 -> \u0049
國 -> \u56FD

Unicode的實(shí)現(xiàn)

同一 Unicode 值可以被編碼成不同的二進(jìn)制表示,以便在存儲(chǔ)和網(wǎng)絡(luò)上傳輸。Unicode的實(shí)現(xiàn):UTF-8、UTF-16、UTF-32、UCS-2等。

UTF-8, Unicode Transformation Format – 8-bit

  • 使用 1 ~ 4 個(gè)字節(jié)變長(zhǎng)編碼表示「1,112,064」個(gè) Unicode 碼點(diǎn)
  • 兼容 ASCII
  • 碼點(diǎn)數(shù)值越小,使用的字節(jié)數(shù)越少,出現(xiàn)的頻率越高

UTF-16

  • 使用 1 ~ 2 個(gè) 16bit 變長(zhǎng)編碼表示「1,112,064」個(gè) Unicode 碼點(diǎn)
  • 它擴(kuò)展于固定16bit長(zhǎng)度的UCS-2

UTF-32

  • 4 字節(jié)定長(zhǎng)編碼
  • 其高位均為0,空間浪費(fèi)比較嚴(yán)重,因此應(yīng)用很少

Java 使用何種編碼

Java char 占 2 個(gè)字節(jié),使用 UTF-16BE 表示一個(gè)字符。由于它只使用 2 個(gè)字節(jié),所以 char 只用能表示部分 UTF-16 編碼,即 0x0000 ~ 0xFFFF。對(duì)于 4 字節(jié)的 UTF-16,需要使用 2 個(gè) char。

String 始終是按 UTF-16BE 處理字符的,對(duì) BMP 字符,使用一個(gè) char,兩個(gè)字節(jié);對(duì)于增補(bǔ)字符,使用兩個(gè) char,四個(gè)字節(jié)。以上是由 Java language spec 規(guī)定的。

Java 源文件默認(rèn)采用平臺(tái)編碼存儲(chǔ),Linux/Unix 是 UTF-8,Window 采用 GBK。一般常用的 IDE 如 Intellij IDEA 和 Eclipse 都能提供多種編碼。編譯器 javac 讀取 Java 源文件時(shí),如果不顯示指定 -encoding,則默認(rèn)以 Charset.defaultCharset() 讀取,如果與源文件的編碼不同,則會(huì)報(bào)錯(cuò)。

javac -encoding gbk/utf-8 僅告訴編譯器以何種編碼讀取 Java 源文件,然后編譯器在編譯時(shí)就用指定的編碼把源文件的字符串轉(zhuǎn)化為UTF-8字符串。

不管 Java 源文件是什么編碼,Java class 字節(jié)碼文件中字符串字面量始終是 UTF-8 編碼,這是由 JVM spec 規(guī)定。

UTF-8 和 GBK2312 編碼的 Java 源文件,分別編譯成 class 文件,兩者相同。

System.out、PrintStream 將會(huì)在輸出之前,把字符串從 UTF-16 轉(zhuǎn)換成默認(rèn)系統(tǒng)編碼(JVM 從操作系統(tǒng)讀?。?。

Java 中把 String 轉(zhuǎn)換成字節(jié)碼,默認(rèn)使用平臺(tái)默認(rèn)的編碼??纯?getBytes 的注釋。

    /**
     * Encodes this {@code String} into a sequence of bytes using the
     * platform's default charset, storing the result into a new byte array.
     *
     * <p> The behavior of this method when this string cannot be encoded in
     * the default charset is unspecified.  The {@link
     * java.nio.charset.CharsetEncoder} class should be used when more control
     * over the encoding process is required.
     *
     * @return  The resultant byte array
     *
     * @since      JDK1.1
     */
    public byte[] getBytes() {
        return StringCoding.encode(value, 0, value.length);
    }
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容