Java字符串对象是否为Chars数组?

我是java的新手,并试图理解该语言的基本要素和基础知识。

是否准确地说Java字符串对象本质上是一个定义为不可变的字符数组的类?

我问这个,因为与char数组和字符串类相比,我对规范感到有点困惑……

JLS 10.9

10.9字符数组不是字符串在Java编程语言中,与C不同,char数组不是String,字符串和char数组都不会被’\ u0000’(NUL字符)终止。 String对象是不可变的,也就是说,它的内容永远不会改变,而char数组有可变元素。 类String中的toCharArray方法返回一个包含与String相同字符序列的字符数组。 StringBuffer类在可变字符数组上实现有用的方法。

JLS 4.3.3

4.3.3类String的类字符串实例表示Unicode代码点的序列。

是否准确地说Java字符串对象本质上是一个定义为不可变的字符数组的类?

不是。一个Java String对象(当前 – 这是我收集的实现细节可能正在改变)一个包含几个字段的类:

  • 包含实际字符的char[]
  • 数组的起始索引
  • 一个长度
  • 缓存哈希码,懒惰计算

索引和长度的原因是几个字符串可以包含对同一个char[]引用。 这被某些操作使用,例如substring (在许多实现中,无论如何)。

重要的是API for String – 这与数组的API非常不同。 当您考虑JLS定义时,您会想到这个API: String表示一系列Unicode代码点。 所以你可以采用Substring序列( Substring ),找到给定的子序列( indexOf ),将其转换为大写序列等。

实际上,JLS称为UTF-16代码单元序列会稍微准确一些; 完全有可能构造一个不是Unicode代码点的有效序列的字符串,例如,通过包含UTF-16代码单元的“代理对”的一半而不包括另一半。 有些部分API在代码单元方面处理String ,但坦率地说, 大多数开发人员大部分时间都在处理字符串,就好像非BMP字符不存在一样。