字符之编码
人类文明的字符在计算机中由二进制代码来表示,呈一一对应关系。
这种映射关系的集合被称之为 【字典】
字符可以在不同的字典下有不同的对应二进制串。
称为 [编码格式】
有
起源:ASCII 码
含中文的:GBK和GB2312
万国码:unicode
···
因为iso机构只协定了unicode字典,并没有设计其在计算机系统中的实现方式
因此出现了
UTF-8 占用1~4个字节
UTF-16 占用2个字节
UTF-32 占用4个字节
三种实现unicode的编码格式。
在java中,
String的value从jvm9开始由byte[]实现,在此前,由char[]实现。
java的默认字符集为utf-8
System.out.println(Charset.defaultCharset());
而jvm的内部编码是utf-16
用java(jdk9及以上版本)可验证:
每个字符长度是不同的,java的String中,中文一般占3个字节(unicode),单词和数字占了一个字节(ascii)
public static void print(String s) {
System.out.println("字符串:"+s);
byte[] B = s.getBytes();
System.out.println("所占字节数:"+B.length);
System.out.println("字节码:");
for (byte aByte : s.getBytes()) {
System.out.println(aByte);
}
System.out.println("----------------------------------");
}
String的value为啥由jdk8的char[]改为了byte[]呢,为了节省空间,如果用char[]则一个字母or数字要用一个字符,占用两个字节,一个汉字要用两个字符,占用四个字节;改用byte[]后,一个字母or数字则仅用一个字节,一个汉字仅用3个字节。
至于utf-8是如何巧妙实现可变长度的,可以有兴趣了解下。
外链
链接: https://www.liaoxuefeng.com/wiki/1016959663602400/1017075323632896.
我们总是在开发中看到吨吨吨、烫烫烫、锟斤拷
byte[] b_gbk = "测试账户".getBytes("GBK"); //b_gbk的长度为2
byte[] b_utf8 = "测试账户".getBytes("UTF-8"); //b_utf8的长度为3
byte[] b_iso88591 = "测试账户".getBytes("ISO8859-1");// b_iso88591的长度为1
byte[] b_unicode = "测试账户".getBytes("unicode"); //b_unicode长度为4
String s_gbk = new String(b_utf8,"GBK");
String s_utf8 = new String(b_utf8,"UTF-8");
String s_iso88591 = new String(b_utf8,"ISO8859-1");
String s_unicode = new String(b_utf8, "unicode");
System.out.println(s_gbk);
System.out.println(s_utf8);
System.out.println(s_iso88591);
System.out.println(s_unicode);
就是把二进制代码用了不符合的编码格式来解译。
譬如英文 jack slow f**k
通过空气的震动传播声音,在中文字典里被翻译成了 杰克斯洛伐克。
20241128加更
找到了更加优秀的博文:
https://www.ruanyifeng.com/blog/2007/10/ascii_unicode_and_utf-8.html