前言

本文参考《Java 核心技术》,同时结合 String 类的源码,整理一些字符串的特性,为后面介绍字符串的使用案例做铺垫。

版本约定

Java 字符串就是 Unicode 字符序列。例如,字符串 “Java\u2122” 是由 5 个 Unicode 字符 J、a、v、a 和 ™ 组成。

我们来看 String 类的源码也可以知道。
image.png
value 就是用来真正存储字符串内容的字段,它是一个 char 类型的数组。

Unicode 字符超过了 65536 个,两个字节已经不能满足描述所有 Unicode 字符的需要了,所以需要通过两个 char 值才能表示(char 类型的存储空间是两个字节)。

为了解决这个问题,Java 使用了码点(code point)和代码单元(code unit)的概念,这个会专门写篇文章描述。

字符串这里就要注意了,其实我们调用 length() 的方法,计算的是 char[] 数组的长度,并不一定是 Unicode 字符的长度。
image.png
length() 方法的注释也描述了,说该方法是计算字符串中 Unicode 代码单元的数量。

比如字符串 “𝕆” 的长度是多少呢?

  1. public static void main(String[] args) {
  2. String str = "𝕆";
  3. System.out.println("字符串 \"\uD835\uDD46\" 的长度是:" + str.length());
  4. }

运行程序,输出:

  1. 字符串 "𝕆" 的长度是:2

不可变

通过上面的描述我们知道,Java 字符串是通过 char 类型的数组存储值的,另外我们注意到该字段是 final 类型。
image.png
String 类也没有提供任何用于修改字符串的方法,所以 Java 中字符串是不可变的,改变字符串,其实是重新生成一个新的字符串。

虽然字符串不可变的特性降低了字符串改变的效率,但是,不可变的字符串也有一个优点:编译器可以让字符串共享。关于字符串共享(字符串池)的概念,后面会专门整理一篇文章,这里就不过多阐述了。

作者:殷建卫 链接:https://www.yuque.com/yinjianwei/vyrvkf/wisvlx 来源:殷建卫 - 架构笔记 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。