Java字符序列——String字符串1.1

前言回顾

java 中的8种基本数据类型。其中, char 是字符类型,占2个字节16位,默认值是 ‘\u0000’ 。用 char 类型的变量来表示单个字符,用单引号引起来。

多个字符按照一定的顺序组成的列表就叫作字符序列

String

——实现了 CharSequence 接口

public final class String
implements java.io.Serializable, Comparable<String>, CharSequence, Constable,
ConstantDesc{	}

字符串是Java中表示字符序列的类。
字符串是不可变的,一旦创建就不能被修改。

字符串的表示

字符串java.lang.String可以用来表示多个字符,用""引起来。字符串是引用数据类
型,默认值是 null

//字符串声明
String str = "我是一个字符串"; // 字面量 比较常用
String str1 = new String("我是一个字符串对象"); // 字符串对象

JDK13 新增文本块(预览),在 JDK15 正式在字符串支持文本块,用 """ 表示。

// Text Block 文本块声明
// 注意第一个"""后面不能写文本,需从下一行开始写
String season = """
	winter""";

String类

public final class String 是用 final 修饰的类,在 Java 中用 final 修饰的类不能被继承,也就是说 String 没有子类。
** 回顾:**

在 Java 中,关键字 final 表示最终的。可以用来修饰类、方法、变量。

  1. 被 final 修饰的类,不能被继承
  2. 被 final 修饰的方法,不能被重写
  3. 被 final 修饰的变量,不能变。如果是基本数据类型不能重新赋值,如果是引用数据类型不
    能改变引用。

字符串具有不可变特性

jdk 1.8及之前版本:

private final char value[]; // 用于存放内容,字符串底层其实就是一个字符数组
private int hash; // 用来存放hash值

jdk1.9及以后版本:

private final byte value[]; // 用于存放内容,1.9之后使用字节数组存储
private int hash; // 用来存放hash值
private byte coder; // 编码方式,0 -LATIN1, 1 - UTF-16

从中我们发现,不管是 jdk 8 及以前还是 jdk 9 及以后版本, value 属性都是 final 的。
就说明,字符串一旦声明就不可变。所以字符串拥有不可变性。

为什么要这么改呢?

主要是为了节约 String 占用的内存,占用内存少引发另外一个好处就是减少 GC 次数。

众所周知,在大多数 Java 程序的堆里, String 占用的空间最大,并且绝大多数 String
只有 Latin-1 字符,这些 Latin-1 字符只需要1个字节就够了。 JDK9 之前, JVM 因为 Str
ing 使用 char 数组存储,每个 char 占2个字节,所以即使字符串只需要1字节/字符,它
也要按照2字节/字符进行分配,浪费了一半的内存空间。

JDK9 是怎么解决这个问题的呢?一个字符串出来的时候判断,它是不是只有 Latin-1 字
符,如果是,就按照1字节/字符的规格进行分配内存,如果不是,就按照2字节/字符的规
格进行分配( UTF-16 编码),提高了内存使用率。

为什么用 UTF-16 而不用 UTF-8 呢?

UTF-8 实际上是对空间利用效率最高的编码集,它是不定长的,可以最大限度利用内存和
网络。但是这种编码集只能用于传输和存储,并不适合拿来做 String 的底层实现。因为 S
tring 有随机访问的方法,所谓随机访问,就是 charAt 、 subString 这种方法。如果字符
串中的每个字符占用的内存是不定长的,那么进行随机访问的时候,就需要从头开始数每
个字符的长度
,才能找到你想要的字符。

使用 UTF-16 编码将它们表示并存储为每个字符2个字节

UTF-16 采用固定长度的编码单元(16位),这使得在访问字符串的任何部分时可以在 O(1) 时间内完成。而 UTF-8 使用可变长度编码单元,因此访问字符串中的字符可能需要 O(n) 时间,其中 n 是字符的位置。

对于 JDK9 和更高版本,默认情况下,如果 String 的行为已更改为对字符串使用紧凑表示
形式。 java 命令文档现在这样说

-XX-CompactStrings

禁用紧凑字符串功能。 默认情况下,启用此选项。 启用此选项后,内部仅包含单字节字符
的 Java 字符串将使用 ISO-8859-1 / Latin-1 编码在内部表示并存储为每个字符的单字节字
符串。 这将只包含单字节字符的字符串减少了50%的空间。 对于包含至少一个多字节字
符的 Java 字符串:使用 UTF-16 编码将它们表示并存储为每个字符2个字节。 禁用紧凑字
符串功能会强制使用 UTF-16 编码作为所有 Java 字符串的内部表示。

需要注意的是,在 Java 9 之后,Java 引入了一些新的 API,如 String::codePoints 和 String::getBytes 等,它们允许开发人员以不同的字符编码方式(包括 UTF-8)来处理字符串。这些 API 提供了更多的灵活性,以满足不同的需求。

你可能感兴趣的:(Java编程,Java理论知识,java,开发语言)