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

9

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

Java字符串对象本质上是由char数组定义的不可变数组类,这种说法是否准确?

我之所以这样问,是因为我对规范与char数组和字符串类的比较有些困惑...

JLS 10.9

10.9 字符数组不是字符串 在Java编程语言中,与C不同,char数组不是字符串,字符串和char数组都不是以'\u0000'(NUL字符)结尾。 字符串对象是不可变的,即其内容永远不会改变,而char数组具有可变元素。 String类中的toCharArray方法返回一个包含与字符串相同字符序列的字符数组。StringBuffer类在可变字符数组上实现了有用的方法。

JLS 4.3.3

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


感谢您发布这个问题。我一直认为String是一个字符数组。:) .. +1 - PermGenError
@chaitanya10:关于你在我现在已删除的答案上提出的问题:一个对象是类的实例。它不是一个类。类和对象是两个不同的东西。 - JB Nizet
1个回答

20
Java字符串对象本质上是一个不可变的字符数组类吗?
不是。Java字符串对象(目前来说——这是一些实现细节,据我了解可能会有所改变)是一个包含以下几个字段的类:
- 包含实际字符的char[] - 起始索引 - 长度 - 缓存的哈希码,延迟计算
索引和长度的原因是,几个字符串可以包含对同一个char[]的引用。这被某些操作(至少在许多实现中是这样)使用,例如substring。
重要的是String的API——它与数组的API非常不同。当你考虑JLS定义时,你会想到的API是:字符串表示Unicode代码点序列。因此,您可以获取子序列(Substring),查找给定子序列(indexOf),将其转换为大写字母序列等等。
事实上,JLS稍微更准确地称其为UTF-16代码单元序列;完全可以构造一个不是Unicode代码点序列的字符串,例如,通过包括UTF-16代码单元的“代理对”的一半但没有另一半。有些API确实根据代码单元处理字符串,但老实说,大多数开发人员在处理字符串时大部分时间都像不存在非BMP字符一样。

很好的回答。您能否解释一下“字符串表示Unicode代码点序列”的含义,以及它与包含实际字符的char[]有何不同?也许这会让非英语为母语的人感到困惑? - kosa
+1 已接受 - 我认为这清楚地回答了我的问题。感谢简明扼要的回答。 - Edward J Beckett

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接