java基礎類型中的char和byte的辨析及Unicode編碼和UTF-8的區別


在平常工作中使用到char和byte的場景不多,但是如果項目中使用到IO流操作時,則必定會涉及到這兩個類型,下面讓我們一起來回顧一下這兩個類型吧。

char和byte的對比

byte

byte 字節,數據存儲容量1byte,byte作為基本數據類型表示的也是一個存儲范圍上的概念,有別於int、long等專門存數字的類型,這種類型的大小就是1byte,而int是4byte。
存數字的話就是1byte=8位,2^8=256 即-128-127。字符的話包括字母和漢字,一個字母是1byte,一個漢字2byte。也就是可以用byte變量去存儲一個英文字符,但是卻存不下一個中文漢字,因為一個漢字占2byte。
總結,byte是java中的一個基本數據類型,這個數據類型的長度是1byte,此byte就是彼byte,即是基本數據類型也是存儲空間的基本計量單位。

char

char是Java中的保留字,與別的語言不同的是,char在Java中是16位的,因為Java用的是Unicode。不過8位的ASCII碼包含在Unicode中,是從0~127的。
Java中使用Unicode的原因是,Java的Applet允許全世界范圍內運行,那它就需要一種可以表述人類所有語言的字符編碼。Unicode。
char本質上是一個固定占用兩個字節的無符號正整數,這個正整數對應於Unicode編號,用於表示那個Unicode編號對應的字符。
由於固定占用兩個字節,char只能表示Unicode編號在65536以內的字符,而不能表示超出范圍的字符。

Unicode和UTF-8的對比

Unicode

需要注意的是,Unicode只是一個符號集,它只規定了符號的二進制代碼,卻沒有規定這個二進制代碼應該如何存儲。
比如,漢字"嚴"的unicode是十六進制數4E25,轉換成二進制數足足有15位(100111000100101),也就是說這個符號的表示至少需要2個字節。表示其他更大的符號,可能需要3個字節或者4個字節,甚至更多。
這里就有兩個嚴重的問題,第一個問題是,如何才能區別Unicode和ASCII?計算機怎么知道三個字節表示一個符號,而不是分別表示三個符號呢?第二個問題是,我們已經知道,英文字母只用一個字節表示就夠了,如果Unicode統一規定,每個符號用三個或四個字節表示,那么每個英文字母前都必然有二到三個字節是0,這對於存儲來說是極大的浪費,文本文件的大小會因此大出二三倍,這是無法接受的。
它們造成的結果是:1)出現了Unicode的多種存儲方式,也就是說有許多種不同的二進制格式,可以用來表示Unicode。2)Unicode在很長一段時間內無法推廣,直到互聯網的出現。

UTF-8

互聯網的普及,強烈要求出現一種統一的編碼方式。UTF-8就是在互聯網上使用最廣的一種Unicode的實現方式。其他實現方式還包括UTF-16(字符用兩個字節或四個字節表示)和UTF-32(字符用四個字節表示),不過在互聯網上基本不用。重復一遍,這里的關系是,UTF-8是Unicode的實現方式之一。
以utf8為例,utf8是一個變長編碼標准,可以以1~4個字節表示一個字符,而中文占3個字節,ascII字符占1個字節。
為什么我們在java里面可以用一個char來表示一個中文呢?
因為java是以unicode作為編碼方式的。unicode是一個定長的編碼標准,每個字符都是2個字節,也就是1個char類型的空間。
在編譯時會把utf8的中文字符轉換成對應的unicode來進行傳輸運算。
 
示例代碼
package com.lingyejun.io;

import java.io.UnsupportedEncodingException;

/**
 * Created by Lingye on 2018/9/28 14:34
 */
public class ChineseCharCode {

    public static void main(String[] args) {
        String str = "中";
        char c = '中';
        // java使用unicode編碼,一個字符占兩個字節
        System.out.println("char字符 中 二進制"+Integer.toBinaryString(c));
        try {
            // UTF-8是Unicode的實現方式之一
            System.out.println(str.getBytes("UTF-8").length);
            // UTF-16也是Unicode的實現方式之一,但使用較少
            System.out.println(str.getBytes("UTF-16").length);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
    }
}

輸出結果及總結

  • 因為Java是以unicode作為編碼方式的。unicode是一個定長的編碼標准,每個字符都是2個字節,也就是1個char類型的空間。
  • Java在編譯時會把utf8的中文字符轉換成對應的unicode來進行傳輸運算。
  • 在Java中,基本類型char,固定占兩個字節,char本質上就是一個無符號的正整數,我們可以使用Integer.toBinaryString(c))將其打印出來。
  • UTF-8采用的是變長字節編碼的方式進行編碼,一個漢字可以以1~4個字節表示一個字符,而中文占3個字節,ascII字符占1個字節。

 

參考文章:https://www.zhihu.com/question/23374078


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM