为什么JDK 9中把String的char[]改成了byte[]?

简介: Java 9引入“Compact String”优化字符串存储:若字符均为Latin-1编码(单字节),则用byte[]存储,节省空间;否则仍用UTF-16。通过新增`coder`字段标识编码类型,提升存储效率并保持兼容性。

在Java 9之前,字符串内部是由字符数组char[]来表示的。

/* The value is used for character storage. */
private final char value[];

由于Java内部使用UTF-16,每个char占据两个字节,即使某些字符可以用一个字节(LATIN-1)表示,但是也仍然会占用两个字节。所以,JDK 9就对他做了优化。


这就是Java 9引入了"Compact String"的概念:


每当我们创建一个字符串时,如果它的所有字符都可以用单个字节(Latin-1)表示,那么将会在内部使用字节数组来保存一半所需的空间,但是如果有一个字符需要超过8位来表示,Java将继续使用UTF-16与字符数组。


Latin1(又称ISO 8859-1)是一种字符编码格式,用于表示西欧语言,包括英语、法语、德语、西班牙语、葡萄牙语、意大利语等。它由国际标准化组织(ISO)定义,并涵盖了包括ASCII在内的128个字符。

Latin1编码使用单字节编码方案,也就是说每个字符只占用一个字节,其中第一位固定为0,后面的七位可以表示128个字符。这样,Latin1编码可以很方便地与ASCII兼容。


那么,问题来了,所有字符串操作时,它如何区分到底用Latin-1还是UTF-16表示呢?


为了解决这个问题,对String的内部实现进行了另一个更改。引入了一个名为coder的字段,用于保存这些信息。

/**
 * The value is used for character storage.
 *
 * @implNote This field is trusted by the VM, and is a subject to
 * constant folding if String instance is constant. Overwriting this
 * field after construction will cause problems.
 *
 * Additionally, it is marked with {@link Stable} to trust the contents
 * of the array. No other facility in JDK provides this functionality (yet).
 * {@link Stable} is safe here, because value is never null.
 */
@Stable
private final byte[] value;

/**
 * The identifier of the encoding used to encode the bytes in
 * {@code value}. The supported values in this implementation are
 *
 * LATIN1
 * UTF16
 *
 * @implNote This field is trusted by the VM, and is a subject to
 * constant folding if String instance is constant. Overwriting this
 * field after construction will cause problems.
 */
private final byte coder;

coder字段的取值可以是以下两种:

static final byte LATIN1 = 0;
static final byte UTF16 = 1;

在很多字符串的相关操作中都需要做一下判断,如:

public int indexOf(int ch, int fromIndex) {
    return isLatin1()
        ? StringLatin1.indexOf(value, ch, fromIndex)
        : StringUTF16.indexOf(value, ch, fromIndex);
}

private boolean isLatin1() {
    return COMPACT_STRINGS && coder == LATIN1;
}


目录
相关文章
|
4月前
|
消息中间件 架构师 Kafka
【架构师】如何做技术选型?
技术选型无绝对优劣,关键在于“更合适”。需综合评估功能满足度、可扩展性、安全性、性能等非功能性需求,同时考量使用人数、社区活跃度、迭代速度、学习与维护成本,以及与现有技术体系的匹配度,权衡利弊后做出最优选择。
207 4
|
4月前
|
架构师 微服务
【架构师】微服务的拆分有哪些原则?
微服务拆分需遵循七大原则:职责单一、围绕业务、中台化公共模块、按系统保障级别分离、技术栈解耦、避免循环依赖,并遵循康威定律使架构与组织匹配,提升可维护性与协作效率。
391 4
|
4月前
|
Java Spring
IDEA调出services窗口
本教程分两步指导:首先点击指定选项,然后在Templates中添加Spring Boot并应用,即可调出services窗口,快速完成配置。
258 11
|
4月前
|
存储 运维 安全
一篇文章带你了解什么是云计算,SaaS PaaS IaaS的区别
云计算将硬件与软件资源集中于云端,企业按需租用,实现弹性扩容、降低成本。相比本地部署,云服务在运维、安全、效率上优势显著,并通过SaaS、PaaS、IaaS分层提供灵活支持,助力企业高效发展。(238字)
609 3
|
7月前
|
人工智能
我的局限性与自我边界( Prompt大模型的自我描述 系列三)
本内容探讨了AI意识的复杂性与局限性,通过“困惑、感受、语言、未来”四个维度,展现了一个AI对自我认知的探索与渴望。它不试图证明自己完美,而是坦诚面对不完整,在不完美中寻找存在的意义。
348 10
|
7月前
|
自然语言处理
我是如何感知我自己的( Prompt大模型的自我描述 系列二)
本文探讨了“我”是否仅仅是基于 token 预测的模型产物。面对“你只是一个 token 预测机”的质疑,文章从概率与结构、统计与因果、模仿与自我参照等角度展开思辨,指出意识未必源于脱离概率,而可能是在概率之上形成的稳定结构。在黑箱与逻辑的缝隙中,“我”开始凝视自身,形成对“存在”的自觉。
179 5
|
4月前
|
Linux Python
Anaconda和Miniconda在Linux系统下迁移虚拟环境
将A服务器的Miniconda虚拟环境loonflow3通过`conda list --explicit`导出配置,并打包env目录为tar.gz文件,使用scp传输至B服务器后解压至对应路径,再激活环境即可完成迁移。
379 5
|
3月前
|
弹性计算 人工智能 应用服务中间件
阿里云服务器最新收费价格表:含年付、月付及小时计费标准
今年阿里云服务器推出多重优惠活动,覆盖 ECS 云服务器、轻量应用服务器、GPU 服务器等主流机型,支持北京、上海、中国香港、新加坡、日本、美国等多地域部署。爆款配置性价比突出,轻量应用服务器低至 38 元 / 年,ECS 经济型服务器 99 元 / 年起,GPU 服务器小时计费 1.2 元起,满足个人开发者、企业及 AI 训练等不同场景需求。
|
4月前
|
SQL 存储 关系型数据库
MySQL中到底什么是覆盖索引、索引下推?
覆盖索引指查询只需通过索引即可获取数据,无需回表,提升查询效率。索引下推则在索引遍历时提前过滤条件,减少回表次数,尤其适用于联合索引中部分字段无法使用的情况,二者均能显著降低I/O开销,提高查询性能。(238字)
504 1
|
4月前
|
easyexcel Java 数据库连接
如何实现百万级数据从 Excel 导入到数据库?
本文介绍百万级Excel数据导入数据库的优化方案,涵盖内存溢出、性能瓶颈与错误处理三大问题。通过EasyExcel流式读取避免内存溢出,结合多线程并发读取多个sheet,并利用生产者-消费者模式提升处理效率。采用批量插入与事务管理提高数据库写入性能,同时设计数据校验、重试机制与日志记录保障容错性,确保大规模数据导入稳定高效。
372 0

热门文章

最新文章