Java9中字符串内部改变浅析

Java8及以前,String内部使用一个char[]保存UTF-16格式字符串,但是这样做有几个问题:如果字符串中主要是ASCII字符,那么用16位的char来保存指利用了8位的ASCII字符相当于浪费了一半的空间在Java起源时,1个16位的char可以完美表示1个16位的UTF-16字符,但是,2^16 = 65536个字符显然无法表示世界上所有奇奇怪怪的字符,包括很多汉字,因此UTF...
摘要由CSDN通过智能技术生成

Java8及以前,String内部使用一个char[]保存UTF-16格式字符串,但是这样做有几个问题:

  1. 如果字符串中主要是ASCII字符,那么用16位的char来保存指利用了8位的ASCII字符相当于浪费了一半的空间
  2. 在Java起源时,1个16位的char可以完美表示1个16位的UTF-16字符,但是,2^16 = 65536个字符显然无法表示世界上所有奇奇怪怪的字符,包括很多汉字,因此UTF-16的标准被修改了,使得有的字符必须用2个16位长的码元来表示,这下就坑爹了,无奈之下,Java只好有些时候用2个char表示一个字符,这2个char被成为代理项对(surrogate pair)。这种情况的出现使得1个字符对应1个char的方便性大大丧失,很多假定1字符1char的API也失效了。
  3. 2中的情况会导致一些令人迷惑的行为,例如当字符串含有emoji字符时,String.length()不等于String.toCharArray().length。这是因为emoji字符必须使用两个char存储,而String.toCharArray().length会返回char的数量(即UTF-16码元数),String.length()则会返回“真实”的、眼睛可以看到的字符数量。曾经,在UTF-16编码一个码元对应一个字符的时代,这两个是相等的。

因此在Java9中,引入了一个叫做紧凑字符串(Compact String)的新特性,在String内部使用byte[]代替char[]。如果字符串的内容都是ISO-8859-1/Latin-1字符(1个字符1byte),则使用ISO-8859-1/Latin-1编码存储字符串,否则使用UTF-16编码存储数组(一个字符2byte或者4byte)。但是为了兼容,String类的方法向外表现的行为是与之前的版本一致的,比如toCharArray()charAt()方法的行为依然和之前一致。

为了支持这一特性,Java引入了StringLatin1StringUTF16两个新的辅助类用来提供静态方法供String类使用,举个例子,为了保证charAt()行为与之前版本的一致,Java9中的代码如下:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值