Java中String类在JDK 8与JDK 11,JDK 17的底层实现变迁

概要

在Java开发中,String 类是最常用的存储字符串之一,它代表了不可变的字符序列。随着JDK版本的更新,String 类的底层实现也在不断演进,以适应不同场景下的性能需求和内存优化。本文将探讨从JDK 8到JDK 11以及JDK17,String 类底层存储类型的变化及其背后的动机。

一,底层类型

在JDK 11中,String 类的底层数据存储机制确实经历了一次重大变革,以适应更高效的空间利用和性能优化需求。具体而言,String 类现在主要依赖于一个byte[]数组和一个额外的byte coder属性来存储和表示字符串值。这种变化尤其体现在处理仅包含ASCII字符或其扩展(即码点不超过U+00FF)的字符串上,此类字符串被称为“紧凑字符串”。

img

在JDK 8中,String 类的底层数据结构是一个字符数组(char[]),这直接映射了Java中对Unicode标准的支持。每个char 类型的变量占据2个字节的空间,能够表示从U+0000到U+FFFF的Unicode码点,涵盖了基本多文种平面(BMP)。这种设计确保了String 对象能够无缝地处理包括中文、日文、韩文在内的多种语言文本。

img

二,"coder"属性

JDK 8中的String类没有"coder"属性,而JDK 11中的String类引入了"coder"属性。这是因为在JDK 8及之前的版本中,Java字符串内部使用的是UTF-16编码,每个字符占用两个字节。在JDK 8中,String类仅保存了一个字符数组(char[])来存储字符串的内容。

而在JDK 9及之后的版本中,Java引入了Compact Strings(紧凑字符串)的概念,以节省内存空间。在这种情况下,String类的实现采用了一种称为Latin-1的编码方式,即对于只包含拉丁字符(Unicode码点小于等于255)的字符串,只需要一个字节来存储每个字符。这样做可以显著减少内存消耗。

为了支持这种新的编码方式,JDK 11中的String类引入了"coder"属性,用于标识字符串使用的编码类型。在JDK 11中,String类内部的字符数组(byte[])只存储Latin-1编码的字符,而针对非拉丁字符的部分,会通过调用StringCoding类的方法进行转码和处理,转码之后依然是byte[]数组

img

img

img

img

可以说JDK 11中的String类引入了"coder"属性是为了支持紧凑字符串的优化,以提高性能和节省内存空间。

jdk选择更换String的底层存储类型的原因是为了降低资源的浪费,char存储是两个字节,而byte存储为1个字节

三,hash 字段

String 内部包含了一个 private 修饰的int 类型的hash 字段 用于缓存字符串的哈希代码 当第一次调用String a 的时候 a会调用HashCode 进行计算哈希码,当下次再次调用a的时候会直接调用hash而不会再调用hashCode 原因是当第一次调用HashCode的时候HashCode 计算哈希码并赋值给hash。如果a的值不发生改变以后的每次调用a都是从hash里面进行获取哈希码进行获取存储的值

img

img

四,hashIsZero 字段

在 JDK 17 中,String 类新增了一个名为 hashIsZero 的私有字段,用于表示字符串的哈希码是否为零。这个字段主要用于优化字符串哈希码的计算和存储。

img

img

在 JDK 17 中,String 类的哈希码计算方式发生了改变。之前的版本中,String 类的哈希码是延迟计算的,即在第一次调用 hashCode 方法时才会计算并缓存哈希码。而在 JDK 17 中,哈希码将在字符串被创建时立即计算,并存储在 hash 字段中。同时,新增的 hashIsZero 字段用于标记哈希码是否为零,以便快速判断字符串的哈希码状态。

这种优化可以提高字符串哈希码的计算和比较性能,并且在某些场景下可以避免不必要的哈希码计算。因此,hashIsZero 字段在新版 JDK 中是为了提升字符串处理的性能而引入的。

JDK 8中,String对象基于char[]数组存储,每个字符占2个字节,支持完整的Unicode编码。到了JDK 11,为了优化内存使用,对于仅包含ASCII或类似单字节编码字符的字符串,String类改用byte[]数组存储,并引入了coder属性标识编码类型,节省了内存。而在JDK 17中,进一步引入了hashIsZero字段来优化哈希码的计算与存储,使得哈希码可以在创建时立即计算并标记是否为零,从而提升性能。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小电玩

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值