編碼字符集
ASCII:最先出現(xiàn)的編碼字符集,包含了大小寫的從A到Z和符號(hào),用8位表示,共258個(gè)字符,老美一開始只固定了前127個(gè)字符(稱為半角),而后面127個(gè)字符是在計(jì)算機(jī)在其他歐美國(guó)家開始使用時(shí)擴(kuò)展的,是擴(kuò)展字符集(全角)。
GB2312和GBK:當(dāng)中國(guó)開始使用計(jì)算機(jī)表示漢字時(shí),ASCII已經(jīng)沒(méi)有空間可以給漢字字符填充,所以中國(guó)索性把兩個(gè)連在一起的大于127的ASCII字符當(dāng)作一個(gè)漢字,這個(gè)方案稱為GB2312;當(dāng)GB2312不足夠表示所有漢字時(shí),中國(guó)規(guī)定 兩個(gè)連在一起的第一個(gè)字符大于127的兩個(gè)ASCII字符當(dāng)作一個(gè)漢字,稱為GBK方案。因此會(huì)出現(xiàn):一個(gè)漢字字符相當(dāng)于兩個(gè)英文字符的情況。
Unicode:當(dāng)計(jì)算機(jī)在全世界廣泛傳播時(shí),出現(xiàn)了許多編碼字符集,各個(gè)編碼字符集之間無(wú)法相互識(shí)別,當(dāng)同時(shí)出現(xiàn)在同一篇文檔中會(huì)出現(xiàn)亂碼。因此國(guó)際標(biāo)準(zhǔn)組織ISO出臺(tái)了一套16位的字符編碼方案以總括現(xiàn)有的各個(gè)編碼字符集, 稱為Unicode。在互聯(lián)網(wǎng)出現(xiàn)之后,ISO規(guī)定了每次傳輸16位的方案稱為UTF-16
字符集編碼
Unicode是無(wú)法用16位表示所有文字字符的,隨著不斷有文字填充,必將使用更多位表示,這就將導(dǎo)致ASCII中的半角前面許多位都是0,白白浪費(fèi)了空間。因此出現(xiàn)了Unicode的字符集編碼方案
UTF-16:Unicode最開始的編碼方案,籠統(tǒng)地用兩個(gè)字節(jié)表示一個(gè)字符,不能解決空間浪費(fèi)的問(wèn)題
UTF-8:網(wǎng)絡(luò)每次傳輸8位,可變長(zhǎng)度的編碼方案,可由1~4個(gè)字節(jié)表示一個(gè)字符,增加標(biāo)識(shí)符以表示多少個(gè)字節(jié)表示一個(gè)字符,更加自由,解決了空間浪費(fèi)問(wèn)題。但也存在問(wèn)題,有些文字由于增加了多個(gè)標(biāo)識(shí)符,導(dǎo)致需要多個(gè)字節(jié)表示,如一個(gè)漢字字符需要三個(gè)字節(jié)表示。
Java中的編碼字符集
I.java.lang.Character類規(guī)定了java使用的編碼字符集,從java.lang.Character類注釋的解讀,我們可以知道:
Java使用了Unicode編碼字符集,具體來(lái)說(shuō)Java中的字符數(shù)值范圍是從0X0000到0x10FFFF,而0x0000到0xFFFF支持UTF-16編碼方案,稱為BMP(Basic Multilingual Plane 基礎(chǔ)多語(yǔ)言面);大于0XFFFF的字符即是擴(kuò)展字符,大小相當(dāng)于兩個(gè)char類型字符。
char類型只支持BMP(即UTF-16包含的字符),char類型數(shù)據(jù)的value是一個(gè)Character類型數(shù)據(jù),如’\u005CuD840’,它代表的是該char類型數(shù)據(jù)在Unicode database中指向的字符,即Character類型不等同于char類型, 如Character.isLetter(’\u005CuD840’)返回的是false,因?yàn)镃haracter.isLetter(char char)要求的是傳入一個(gè)char類型的數(shù)據(jù),但該語(yǔ)句中傳入的是Character類型的數(shù)據(jù)
int類型除了支持BMP外還支持?jǐn)U展字符,如 Character.isLetter(0x2F81A)返回的是true,0x2F81A是一個(gè)擴(kuò)展字符的數(shù)值.注釋原文如下:
* <p>A {@code char} value, therefore, represents Basic
* Multilingual Plane (BMP) code points, including the surrogate
* code points, or code units of the UTF-16 encoding. An
* {@code int} value represents all Unicode code points,
* including supplementary code points. The lower (least significant)
* 21 bits of {@code int} are used to represent Unicode code
* points and the upper (most significant) 11 bits must be zero.
* Unless otherwise specified, the behavior with respect to
* supplementary characters and surrogate {@code char} values is
* as follows:
*
* <ul>
* <li>The methods that only accept a {@code char} value cannot support
* supplementary characters. They treat {@code char} values from the
* surrogate ranges as undefined characters. For example,
* {@code Character.isLetter('\u005CuD840')} returns {@code false}, even though
* this specific value if followed by any low-surrogate value in a string
* would represent a letter.
*
* <li>The methods that accept an {@code int} value support all
* Unicode characters, including supplementary characters. For
* example, {@code Character.isLetter(0x2F81A)} returns
* {@code true} because the code point value represents a letter
* (a CJK ideograph).
* </ul>
*
* <p>In the Java SE API documentation, <em>Unicode code point</em> is
* used for character values in the range between U+0000 and U+10FFFF,
* and <em>Unicode code unit</em> is used for 16-bit
* {@code char} values that are code units of the <em>UTF-16</em>
- II.Character類中提供了判斷字符是BMP還是擴(kuò)展字符的方法
public static final char MIN_VALUE = '\u0000';
public static final char MAX_VALUE = '\uFFFF';
public static final int MIN_CODE_POINT = 0x000000;
public static final int MAX_CODE_POINT = 0X10FFFF;
public static boolean isBmpCodePoint(int codePoint) {
return codePoint >>> 16 == 0;
// Optimized form of:
// codePoint >= MIN_VALUE && codePoint <= MAX_VALUE
// We consistently use logical shift (>>>) to facilitate
// additional runtime optimizations.
}
public static boolean isValidCodePoint(int codePoint) {
// Optimized form of:
// codePoint >= MIN_CODE_POINT && codePoint <= MAX_CODE_POINT
int plane = codePoint >>> 16;
return plane < ((MAX_CODE_POINT + 1) >>> 16);
}
提供了將擴(kuò)展字符從數(shù)值轉(zhuǎn)為字符類型的方法
//從此處我們可以發(fā)現(xiàn),一個(gè)擴(kuò)展字符相當(dāng)兩個(gè)char類字符
static void toSurrogates(int codePoint, char[] dst, int index) {
// We write elements "backwards" to guarantee all-or-nothing
dst[index+1] = lowSurrogate(codePoint);
dst[index] = highSurrogate(codePoint);
}
學(xué)習(xí)內(nèi)容來(lái)自周華健的網(wǎng)課《[9節(jié)課征服「字符編碼」]》https://edu.51cto.com/sd/1c7de