1、典型回答
String 底层是基于数组实现的,并且数组使用了 final 修饰,不同版本中的数组类型也是不同的:
- JDK9 之前(不含JDK9) String 类是使用 char[ ](字符数组)实现的
- 但 JDK9 之后,String 使用的是 byte[ ] (字节数组)实现的
注:1个字符(char) = 2个字节(byte)
String 实现源码如下(JDK21):
2、全面剖析
String底层是基于 char[ ] 数组或 byte[ ] 数组实现的,JDK9 之后,之所以使用 byte[ ] 替换 char[ ] 数组,这是因为,byte类型粒度更细,一个 char 等于 2 个 byte。对于大部分的英文字符和少量中文字符来说,使用 1 个 byte就够了,完全不需要使用 1 个 char 进行存储,所以 JDK9 使用 byte[ ] 之后,对于大部分英文字符来说,同样的内容,其存储空间减少了一半,这就是 JDK9 之后使用 byte[ ] 所带来的优势
3、知识扩展
字符串存储在 JVM 的哪个区域?
String字符串的值是存储在字符串常量池的,而字符串常量池在 《Java 虚拟机规范》中是属于方法区,但在 JVM 默认的虚拟机 Hotspot 中,在 JDK7 的时候就将 字符串常量池 和 静态变量 从方法区的具体实现永久代中移除,放到堆上了。
之后的版本(JDK8 之后)移除了永久代,取而代之的是元空间,它是存储在本地内存(也叫直接内存)中的,但字符串常量池和静态变量依然存储在堆上,并未改动