Java String是Java API中最常用的类,本文和大家谈谈String类的内部原理,同时描述ISO-8859-1字符集在字符串处理中的独特用处。
Java字符串的内部编码
String类内部管理着一个char类型的数组,Java API是这样描述char基本类型的:
char 数据类型(和 Character 对象封装的值)基于原始的 Unicode 规范,将字符定义为固定宽度的 16 位实体。
这一点我们可以通过下面的语句加以证实:
System.out.println(Character.SIZE); // 结果为16
System.out.println(Character.SIZE); // 结果为16
根据String类的构造方法,我们可以这样定义字符串:
String str = "abc";
String str = "abc";
上句代码等效于:
char data[] = {'a', 'b', 'c'};
String str = new String(data);
char data[] = {'a', 'b', 'c'};
String str = new String(data);
同时,char基本类型与byte、short、int、long一样可以用数值表示。所以上述代码等效于:
char data[] = {0x61, 0x62, 0x63};
String str = new String(data);
char data[] = {0x61, 0x62, 0x63};
String str = new String(data);
需要注意的是,char基本类型始终使用16位即两个字节表示一个字符,即使这个字符的Unicode值小于0xFF(如ASCII码)。对于Unicode值大于0xFF的字符,如“中国”二字的Unicode编码分别为\u4E2D和\u56FD,我们可以这样创建:
char data[] = {'\u4E2D', '\u56FD'};
String str = new String(data);
char data[] = {'\u4E2D', '\u56FD'};
String str = new String(data);
当然也可以这样创建:
char data[] = {0x4E2D, 0x56FD};
String str = new String(data);
char data[] = {0x4E2D, 0x56FD};
String str = new String(data);
通过上面的描述可以明确两个要点:
字符串对象中的每一个元素始终占据两个字节长度,一个或两个元素(增补字符占据两个元素)表示一个字符。
字符串对象中的每一个元素都使用Unicode字符集进行编码。
字符集(Charset)与字节化字符数据
在出现 Unicode 规范之前,计算机在处理字符串的问题上经历过ASCII和ANSI编码两个阶段,在ASCII时代,计算机只能处理英文数字以及几个基本符号,当时使用的是单字节字符集(SBCS)。
各国为了能在计算机上处理本国的文字,制订了相应的国家标准,规定了各自的ANSI编码。如中文简体使用GBK标准;中文繁体使用BIG5标准;日文使用Shift_JIS标准。在ANSI编码时代,计算机使用多字节字符集(MBCS)处理文字。如“中国ABC”,在GB2312标准中,“中国”两个字符分别使用两个字节表示,而“ABC”三个英文字符又分别使用一个字节表示。各国文字的ANSI编码互不通用,不能使用一种ANSI编码表达多个国家的文字。
为了文字交流的顺畅,也就是说为了达到在一个文本当中既可以有中文简体字存在,也可以有中文繁体字存在的目的。国际组织根据各国语言的特点,使用两个字节的数据量将大部分国家的文字信息整合到一个字符集中,这就是Unicode编码,也称万国码。关于Unicode编码的特点,前文已经描述,那就是使用双字节字符集(DBCS)处理文字。