作者:鸟窝
来源:https://colobu.com/
文章插图
依照JAVA的文档 , Java中的字符内部是以UTF-16编码方式表示的 , 最小值是 \u0000 (0),最大值是\uffff(65535) , 也就是一个字符以2个字节来表示 , 难道Java最多只能表示 65535个字符?
char: The char data type is a single 16-bit Unicode character. It has a minimum value of '\u0000' (or 0) and a maximum value of '\uffff' (or 65,535 inclusive).首先 , 让我们先看个例子:
from The Java™ Tutorials
public class Main { public static void main(String[] args) { // 中文常见字 String s = "你好"; System.out.println("1. string length =" + s.length()); System.out.println("1. string bytes length =" + s.getBytes().length); System.out.println("1. string char length =" + s.toCharArray().length); System.out.println(); // emojis s = ""; System.out.println("2. string length =" + s.length()); System.out.println("2. string bytes length =" + s.getBytes().length); System.out.println("2. string char length =" + s.toCharArray().length); System.out.println(); // 中文生僻字 s = "妹"; System.out.println("3. string length =" + s.length()); System.out.println("3. string bytes length =" + s.getBytes().length); System.out.println("3. string char length =" + s.toCharArray().length); System.out.println(); }}运行这个程序 , 你觉得输出结果是什么?
输出结果:
1. string length =21. string bytes length =61. string char length =22. string length =42. string bytes length =82. string char length =43. string length =33. string bytes length =73. string char length =3我们知道 , String.getBytes()如果不指定编码格式 , Java会使用操作系统的编码格式得到字节数组 , 在我的macOS中 , 默认使用UTF-8作为字符编码(locale命令可以查看操作系统的编码) , 所以在我的机器运行 , String.getBytes()会返回UTF-8编码的字节数组 。
- String.length返回Unicode code units的长度 。
- String.toCharArray返回字符数组 。
- 普通的中文字:字符串的长度是2 , 每个中文字按UTF-8编码是三个字节 , 字符数组的长度看起来也没问题
- emojis字符:我们设置了两个emojis字符 , 男女头像 。结果字符串的长度是4, UTF-8编码8个字节 , 字符数组的长度是4
- 生僻的中文字:我们设置了两个中文字 , 其中一个是生僻的中文字 。结果字符串的长度是3 , UTF-8编码7个字节 , 字符数组的长度是3
这还得从Java的历史说起 。
Java最初设计的Charactor用两个字节来表示unicode字符 , 这没有问题 , 因为最初unicode中的字符还比较少 , Java 1.1之前采用Unicode version 1.1.5, JDK 1.1中支持Unicode 2.0, JDK 1.1.7支持Unicode 2.1, Java SE 1.4 支持 Unicode 3.0, Java SE 5.0开始支持Unicode 4.0 。
直到Unicode 3.0, Java用两个字节来表示unicode字符还没有问题 , 因为Unicode 3.0最多49,259个字符 , 两个字节可以表示65,535个字符 , 还足够容的下所有的uicode3.0字符 。
但是Unicode 4.0(事实上自Unicode 3.1), 字符集进行很大的扩充 , 已经达到了96,447个字符 , Unicode 11.0已经包含137,374个字符 。
在Unicode中 , 为每一个字符对应一个编码点(一个整数) , 用 U+紧跟着十六进制数表示 。所有字符按照使用上的频繁度划分为 17 个平面(编号为 0-16) , 即基本的多语言平面和增补平面 。基本的多语言平面(英文为 Basic Multilingual Plane , 简称 BMP)又称平面 0 , 收集了使用最广泛的字符 。
这样一来 , Java的Charactor的两个字节的设计 , 已经不足以容纳所有的Unicode 4的字符 , 所以可能需要4个字节才能表示扩展字符 , 所以现在的Charactor代表的已经不再是一个字符 (代码点 code point), 而是一个代码单元(code unit) 。
- Code Point:代码点 , 一个字符的数字表示 。一个字符集一般可以用一张或多张由多个行和多个列所构成的二维表来表示 。二维表中行与列交叉的点称之为代码点 , 每个码点分配一个唯一的编号数字 , 称之为码点值或码点编号 , 除开某些特殊区域(比如代理区、专用区)的非字符代码点和保留代码点 , 每个代码点唯一对应于一个字符 。从U+0000 到 U+10FFFF 。
推荐阅读
- C语言中史上最有意思的BUG,一个就算是高手也会犯的BUG
- 你知道Redis的字符串是怎么实现的吗?
- 一个月孕妇能练习瑜伽吗?
- 马其顿在哪 马其顿位置地图
- 山姆会员两个人如何用一个会员 山姆会员可以两个人用一个吗
- 洗碗池下水道反味怎么办?一个简单的方法,轻松解决,涨知识了
- 迷迭香蓖麻油一定要三天吗 蓖麻油迷迭香一个月能用几次
- 阿根廷人,吃烤肉喝马黛茶
- 梦见大洪水来了成功逃生还救了一个小孩子 梦见大洪水来了成功逃生还捡到很多钱
- 三步了解JavaScript的组成