https://blog.csdn.net/weixin_37703598/article/details/80679376html
咱們並非在寫代碼,咱們只是將本身的思想經過代碼表達出來!java
1 將思惟變現成爲一行代碼,是從抽象思惟到具體代碼的編碼過程;繼而計算機再將咱們的代碼再解碼爲計算機能處理的形式--2進制數字。程序員
2 當計算機須要向你展現數據時它還須要將2進制數字參照必定的規則(碼錶)編碼爲人所能理解的格式。算法
若是不能清楚的理解編碼和解碼的原理和規則,我想做爲程序猿的你是必定會善罷甘休的吧。哈哈,請隨個人思路一塊兒,讓咱們知其因此然吧!數據庫
咱們這裏只討論狹義的計算機字符編碼問題,如下論述都是基於此條件之下,才疏學淺,若有錯誤請同窗們不吝賜教哦。數組
字符編碼瀏覽器
1 總論服務器
What/定義:編碼是信息從一種形式或格式轉換爲另外一種形式的過程,而解碼是其逆過程。數據結構
Why/爲何須要編碼:見開篇。編碼
How/怎麼編碼:人們發明了不少碼錶,編碼和解碼實際上就是在查不一樣的碼錶(好像字典)的過程。
2 碼錶
2.1 祖宗:ASCII(American Standard Code for Information Interchange,美國標準信息交換代碼),這是個單字節編碼表,它能最多能表示256個字符(但實際上只用了7bit,128個。ISO8859-1使用8bit來表示,能表示256)。
(引用百度百科的圖片,侵刪)
2.2 Unicode
0000..007F; Basic Latin
0080..00FF; Latin-1 Supplement
0100..017F; Latin Extended-A
0180..024F; Latin Extended-B
0250..02AF; IPA Extensions
02B0..02FF; Spacing Modifier Letters
0300..036F; Combining Diacritical Marks
0370..03FF; Greek
0400..04FF; Cyrillic
0530..058F; Armenian
0590..05FF; Hebrew
0600..06FF; Arabic
0700..074F; Syriac
0780..07BF; Thaana
0900..097F; Devanagari
0980..09FF; Bengali
0A00..0A7F; Gurmukhi
0A80..0AFF; Gujarati
0B00..0B7F; Oriya
0B80..0BFF; Tamil
0C00..0C7F; Telugu
0C80..0CFF; Kannada
0D00..0D7F; Malayalam
0D80..0DFF; Sinhala
0E00..0E7F; Thai
0E80..0EFF; Lao
0F00..0FFF; Tibetan
1000..109F; Myanmar
10A0..10FF; Georgian
1100..11FF; Hangul Jamo
1200..137F; Ethiopic
13A0..13FF; Cherokee
1400..167F; Unified Canadian Aboriginal Syllabics
1680..169F; Ogham
16A0..16FF; Runic
1780..17FF; Khmer
1800..18AF; Mongolian
1E00..1EFF; Latin Extended Additional
1F00..1FFF; Greek Extended
2000..206F; General Punctuation
2070..209F; Superscripts and Subscripts
20A0..20CF; Currency Symbols
20D0..20FF; Combining Marks for Symbols
2100..214F; Letterlike Symbols
2150..218F; Number Forms
2190..21FF; Arrows
2200..22FF; Mathematical Operators
2300..23FF; Miscellaneous Technical
2400..243F; Control Pictures
2440..245F; Optical Character Recognition
2460..24FF; Enclosed Alphanumerics
2500..257F; Box Drawing
2580..259F; Block Elements
25A0..25FF; Geometric Shapes
2600..26FF; Miscellaneous Symbols
2700..27BF; Dingbats
2800..28FF; Braille Patterns
2E80..2EFF; CJK Radicals Supplement
2F00..2FDF; Kangxi Radicals
2FF0..2FFF; Ideographic Description Characters
3000..303F; CJK Symbols and Punctuation
3040..309F; Hiragana(日文平假名)
30A0..30FF; Katakana(日文片假名)
3100..312F; Bopomofo
3130..318F; Hangul Compatibility Jamo
3190..319F; Kanbun
31A0..31BF; Bopomofo Extended
3200..32FF; Enclosed CJK Letters and Months
3300..33FF; CJK Compatibility
3400..4DB5; CJK Unified Ideographs Extension A
4E00..9FFF; CJK Unified Ideographs
A000..A48F; Yi Syllables
A490..A4CF; Yi Radicals
AC00..D7A3; Hangul Syllables
D800..DB7F; High Surrogates
DB80..DBFF; High Private Use Surrogates
DC00..DFFF; Low Surrogates
E000..F8FF; Private Use
F900..FAFF; CJK Compatibility Ideographs
FB00..FB4F; Alphabetic Presentation Forms
FB50..FDFF; Arabic Presentation Forms-A
FE20..FE2F; Combining Half Marks
FE30..FE4F; CJK Compatibility Forms
FE50..FE6F; Small Form Variants
FE70..FEFE; Arabic Presentation Forms-B
FEFF..FEFF; Specials
FF00..FFEF; Halfwidth and Fullwidth Forms
FFF0..FFFD; Specials
10300..1032F; Old Italic 10330..1034F; Gothic
10400..1044F; Deseret
1D000..1D0FF; Byzantine Musical Symbols
1D100..1D1FF; Musical Symbols
1D400..1D7FF; Mathematical Alphanumeric Symbols
20000..2A6D6; CJK Unified Ideographs Extension B
2F800..2FA1F; CJK Compatibility Ideographs Supplement
E0000..E007F; Tags
F0000..FFFFD; Private Use
100000..10FFFD; Private Use
最經常使用的CJK(Chinese Japanese Korean 中日韓文)區間段是4E00~9FFF,但9FA6~9FFF仍是空的,因此實際有值得是4E00~9FA5,這也是大部分人判斷中文所用的區段。但你們要知道,其實CJK大部分是描述的中文,日文和韓文還有相應的區間。上表中帶有CJK的、平假名Hiragana、片假名Katakana、朝鮮文Hangul的都是中日韓文可能的字符區間:
CJK Unified Ideographs
只是經常使用的區間,所有CJK區間應該是:
2E80..2EFF(11904-12031): CJK Radicals Supplement
3000..303F(12288-12351): CJK Symbols and Punctuation
3040..309F(12352-12447): Hiragana(日文平假名)
30A0..30FF(12448-12543): Katakana(日文片假名)
3130..318F(12592-12687): Hangul Compatibility Jamo(朝鮮文兼容字母)
31F0..31FF(12784-12799): Katakana Phonetic Extensions(日文片假名語音括展)
3200..32FF(12800-13055): Enclosed CJK Letters and Months
3300..33FF(13056-13311): CJK Compatibility
3400..4DB5(13312-19893): CJK Unified Ideographs Extension A
4E00..9FFF(19968-40959): CJK Unified Ideographs
AC00..D7AF(44032-55215): Hangul Syllables(朝鮮文音節)
F900..FAFF(63744-64255): CJK Compatibility Ideographs
FE30..FE4F(65072-65103): CJK Compatibility Forms
20000..2A6D6(131072-173782): CJK Unified Ideographs Extension B
2F800..2FA1F(194560-195103): CJK Compatibility Ideographs Supplement
UCS-2編碼(16進制) UTF-8 字節流(二進制)
0000 - 007F 0xxxxxxx
0080 - 07FF 110xxxxx 10xxxxxx
0800 - FFFF 1110xxxx 10xxxxxx 10xxxxxx
使用Unicode的推薦字節順序標記方法BOM(Byte Order Mark)。
它的方法是:UCS中有個字符叫"ZERO WIDTH NO-BREAK SPACE",它編碼爲FE FF,還有個字符FF FE在UCS中不存在。
UCS規範建議咱們在傳輸字節流最前,先傳輸字符FE FF代表字節流是Big-Endian;傳輸FF FE代表字節流是Little-Endian。
2.3 中國
GB GB2312 GBK 是國標以及其擴展碼錶。佔用雙字節。
BIG5是臺灣/香港使用的繁體字符集。
GBK整體範圍爲:0x8140~0xFEFE,首字母在0x81~0xFE之間,尾字節在0x40~0xFE之間,剔除0x**7F一條線,總計23940個碼位,收入21886個漢字(21003)和圖形符號(883)。
JAVA
好了,我是Java程序員,我只爲了理解《Tinking in java》中的一句話才搞了一天時間來研究這個問題的,好在仍是有點成果!!
「java中有個基本類型char,它佔用固定的2byte空間來表示字符,又由於java設計之初就採用了Unicode編碼,因此char能表示全部字符包括中文。」
看到滿世界這樣的答案,我就不相信了!2字節最多隻能標識65536個字符,它是怎麼能囊括那麼多字符的呢??僅全部漢字就不止6萬吧!!!!
好了,無論你看沒看完上邊的文章,我告訴你結論就好!
結論
1. char
java中的char確實使用2Byte空間,它實際使用的是UCS-2 也就是plane 0,只能表述65536個字符,對於超出其範圍的其它plane內容,請看下圖:
一旦你使用了大於UCS-2的字符,那麼編譯器會直接報錯!
其實也就是說char使用的是UTF-16格式。有個建議是儘可能別用char類型,由於它會致使一些隱蔽的錯誤。好比,當你在用String時你定義了一個「蟲」,你想固然的認爲一個char就能盛放String中的一個字符(畢竟char是字符,而String就是描述的char數組),可是你會發現其實這個String的length()是2而不是1,由於它超出了UCS-2,String用兩個char的位置(4字節)來表示了這個char,而String本該用一個char的位置來表示它纔對。
2. String
首先,String可以支持的字符與你寫代碼時選擇的編碼方式有關,當你選擇UTF編碼時,你能夠隨便使用Unicode字符,用沒腳」蟲「當變量名都隨你。使用GB*時,沒腳蟲」蟲「不被支持(GBK收錄的少一些吧或者這是日本字吧?)
其次,String在Java中是被定義爲char數組來組織的,因此你定義的String最終要被轉換成char來存放,可是,不要認爲超出char的65536就不能存了,若是超出了它會用2個char來存放
在這裏我想用兩種方向來講1個String佔用的空間
1. 在Java中實際使用的空間
這與使用的編碼有關
UTF-8:2/4byte,其實就是1個char或者2個char;
GB*:2byte,就是1個char;
2. 若是對其編碼,所須要的空間(String.getBytes())
UTF-8:1~4byte,ASCII用1Byte,漢字大部分用3Byte,其它字符參照上邊UTF2.2的算法,超出UCS-2的部分好比那個「蟲」就會是4Byte;
GB*:ASCII使用1Byte,其它中文2Byte;
3. 額外的部分---從java到class文件
不管.java文件你用GBK或者UTF-8來編碼,編譯器在將其編譯爲.class文件後,若是其中有字符串,會使用UTF-8來編碼存儲字節,佔用1-4Byte。詳細來講,就是在.class文件的常量池部分,這種字符串數據使用的數據結構是CONSTANT_Utf8_info,表明UTF-8編碼的字符串。
最後吐槽一下!!!我打了3遍才把發佈好這最後一段,一旦我打了那個少一腿的」蟲「字,我後邊的東西就被吃了,是保存到數據庫時直接給我後邊的忽視了嗎???