Java |  char

猜一下这段java 代码结果输出什么?

System.out.println("𐐀".length());

Unicode 字符定义

Unicode 定义了全球所有文字(字符)的编码标准,一个字符对应一个编码(数字)。最开始使用2个字节来表示所有字符,这也是为什么java char 使用两个字节来表示字符的原因,但是2个字节不能完全表示所有的字符,所以编码后面扩展到了3个字节。
1、 基本字符表示从 U+0000 到 U+FFFF 之间的字符集,也被成为基本多语言面(BMP)
2、增补字符表示从 U+010000 到 U+10FFFF 范围之间的字符集。

March 2020, there is a repertoire of 143,859 characters.
Private Use Area: U+E000–U+F8FF (6,400 characters).
Supplementary Private Use Area-A: U+F0000–U+FFFFD (65,534 characters).
Supplementary Private Use Area-B: U+100000–U+10FFFD (65,534 characters).

unicode 编码扩展了,java 的char 怎么办,表示不了了?

The Java platform uses the UTF-16 representation in char arrays and in the String and StringBuffer classes. In this representation, supplementary characters are represented as a pair of char values, the first from the high-surrogates range, (\uD800-\uDBFF), the second from the low-surrogates range (\uDC00-\uDFFF).

java 默认使用UTF-16 来进行unicode 编码,如果unicode 大于了2个字节,java 使用两个char 来表示。上面示例中 “𐐀” unicode == U+10400,所以会被解析成两个char。

Unicode 相关术语

character :
书写系统中文本的最小表示单元

character set :
character 集合

code point:
代码点,unicode 字符对应的编码的数字,比如U+10400 就是一个代码点

code space :
unicode 代码点的范围,U+0000 -- U+10FFFF

code unit :
对代码点进行二次编码的最小单位(1 byte,2 byte ,4 byte),一个字符可能由多个code unit 编码组成,见后续unicode 实现。

codepage、codemap:
表示码表,编码与字符的映射关系

Unicode 实现

Unicode 标准定义了一个字符对应一个数字,这个数字可以是2个字节,也可以是3个字节。我们程序要对这个数字进行解析,就需要判断是2个字节组成一个字符,还是三个字节组成一个字符。常用的编码方式有 UTF-8、 UTF-16、 UTF-32,如果是需要在网络中传输,还需求定义大端小端。

UTF-8

code unit 为1个字节,UTF-8 编码unicode 后结果为1-4 个字节,这样我们就可以从第一个字节来判断后续还有多少个字节。


UTF-8.png
UTF-16

code unit 为2个字节,UTF-16编码unicode 后结果为 2、4 个字节


UTF-16.png
UTF-32

code unit 为4个字节,UTF-32编码unicode 后结果为 4 个字节

例如:
"abc" U+10400

 UTF-8编码:61, 62, 63, f0, 90, 90, 80
 UTF-16编码:0061, 0062, 0063, d801, dc00
 UTF-32编码:00000061, 00000062, 00000063, 00010400
Java 字符集实现

java 源文件编码可以定义文件编码方式 ,比如gbk,utf-8,utf-16。java编译器把java 源文件统一编译成unicode(UTF-16)格式存储。可以使用 javac -encoding encoding 自定源文件的编码。

java 是怎么实现编码格式的转换的呢?
java 会对每一种字符集编码与unicode 编码做一个对应关系,这样只要我们知道任何一种编码,都能够转换为unicode 编码。

例如 GBK
b2cStr :就是一个codepage (码表),里面定义所有中文字符与unicode的对应关系。


b2cStr.png
b2cStr.png

b2cStr 为什么定义一个字符数组,因为gbk 编码 为一个数组 例如娩 编码为C3E4,用数组可以方便映射。


GBK 编码举例.png

代码测试

 Charset charset =Charset.forName("gbk");
    ByteBuffer buffer = ByteBuffer.wrap(new byte[]{(byte)0xc3,(byte)0xe4});
    CharBuffer decode = charset.decode(buffer);
    IntStream chars = decode.chars();
    chars.forEach(i->{
      //ux5a29
      System.out.println(i);
    });
    System.out.println(charset.decode(buffer));

输出

char 的值0x5a29 对应的unicode 编码也为娩


娩.png
输入法与字符集

1、输入法 依据键盘点位查找操作系统对应的字符集,并且找到字符集对应的编码
2、输入法把codepoint 传递给应用程序,应用程序按照指定编码方式对codepoint 进行编码
3、应用程序编码后,存储到磁盘。

比如在windows 系统中,我们可以自定义字符,然后关联一个codepoint ,输入法选择使用codepoint 方式输入。输入对应的codepoint 后,就可以显示为自己构造的字符。应用程序接受到codepoint 后,按照指定的编码方式进行编码。

参考资料:

https://en.wikipedia.org/wiki/Unicode
http://unicode.org/glossary/#coded_character
https://en.wikipedia.org/wiki/Glyph
https://en.wikipedia.org/wiki/Character_encoding
https://en.wikipedia.org/wiki/GBK_(character_encoding)
http://www.khngai.com/chinese/charmap/tblgbk.php?page=0
http://tools.jb51.net/table/gbk_table
https://docs.oracle.com/javase/7/docs/api/java/lang/Character.html

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,547评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,399评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,428评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,599评论 1 274
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,612评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,577评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,941评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,603评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,852评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,605评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,693评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,375评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,955评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,936评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,172评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,970评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,414评论 2 342