为什么 String、StringBuffer 和 StringBuilder 类使用字节数组而不是字符数组来存储字符串的字符?

my *_*YAN 2 java string stringbuilder stringbuffer java-9

一个字节不能容纳来自世界上各种语言的字符的 unicode。所以使用字节数组我们不能有不同语言的字符串。为什么这些类使用字节数组而不是字符数组?

更新:

class First
{
        public static void main(String[] args)
        {
                System.out.println();
                String s = "\u0935\u0902\u0926\u0947 \u092e\u093e\u0924\u0930\u092e\u094d";
                String s1 = "???? ??????";
                System.out.println(sb);
                System.out.println(sb1);
        }
}
Run Code Online (Sandbox Code Playgroud)

我认为上面的字符串每个字符需要两个字节。它们如何可以容纳在一个字节中?

Sla*_*law 5

使用byte[]是 Java 9 中引入的优化。此更改的目标/动机在JEP 254: Compact Strings 中进行了描述。

概括

为字符串采用更节省空间的内部表示。

目标

提高 String 类和相关类的空间效率,同时在大多数场景下保持性能并保持对所有相关 Java 和本机接口的完全兼容性。

非目标

在字符串的内部表示中使用替代编码(例如 UTF-8)并不是目标。随后的 JEP 可能会探索这种方法。

动机

String 类的当前实现将字符存储在 char 数组中,每个字符使用两个字节(十六位)。从许多不同应用程序收集的数据表明,字符串是堆使用的主要组成部分,而且,大多数 String 对象仅包含 Latin-1 字符。此类字符仅需要一个字节的存储空间,因此此类 String 对象的内部字符数组中的一半空间将被闲置。

描述

我们建议将 String 类的内部表示从 UTF-16 字符数组更改为字节数组加上编码标志字段。新的 String 类将根据字符串的内容存储编码为 ISO-8859-1/Latin-1(每个字符一个字节)或 UTF-16(每个字符两个字节)的字符。编码标志将指示使用哪种编码。

与字符串相关的类,如 AbstractStringBuilder、StringBuilder 和 StringBuffer 将更新为使用相同的表示,HotSpot VM 的内部字符串操作也将更新。

这纯粹是一个实现更改,对现有公共接口没有任何更改。没有计划添加任何新的公共 API 或其他接口。

迄今为止完成的原型设计工作证实了内存占用的预期减少、GC 活动的显着减少以及在某些极端情况下的轻微性能回归。