String类

String 类的核心特性说明

一、接口与修饰符实现

  1. final 修饰

    String 类被final关键字修饰,意味着它不能被继承,所有方法无法被重写,保证了类行为的稳定性。

  2. 序列化支持

    实现Serializable接口(空接口),表示 String 对象可被序列化,支持网络传输或持久化存储。

  3. 比较与排序能力

    实现Comparable<String>接口,可通过compareTo()方法进行字符串比较,支持自然排序。

  4. 字符串基础操作定义

    实现CharSequence接口,规定了字符串必须实现的核心方法,包括:

    • length():返回长度
    • toString():返回字符串本身
    • charAt(int index):获取指定位置字符等
  5. JDK 12 + 新增接口

    实现ConstableConstantDesc接口,支持在常量表达式中使用字符串,增强编译期常量处理能力。

二、内部数据结构

  • JDK 8 及之前:底层使用private final char[] value存储字符(每个字符占 2 字节)。
  • JDK 9 及之后:优化为private final byte[] value(默认 UTF-8 编码,根据字符范围动态占用 1-2 字节),减少内存占用。

三、不可变性(Immutable)

String 对象是常量,创建后其值无法修改,核心原因:

  1. 类被final修饰,禁止继承重写方法。
  2. 底层存储数组valueprivate final修饰,无法修改引用指向,且无对外暴露修改数组的方法。

四、不可变设计的优势

  1. 线程安全

    多线程环境下无需额外同步,可安全共享 String 对象(不会因并发修改导致数据不一致)。

  2. 安全性保障

    避免因一处修改导致所有引用该对象的地方受影响(例如网络请求参数、文件路径等关键字符串)。

  3. 字符串常量池复用

    不可变性使常量池中的字符串可被多个引用共享,减少内存消耗。

五、字符串的两种创建方式

创建方式 底层逻辑
String s = "中国"; 1. 先检查字符串常量池中是否存在 “中国”;

2. 存在则直接返回常量池中的对象引用;

3. 不存在则在常量池创建 “中国”,再返回引用。
String s = new String("中国"); 1. 先执行上述 “字面量创建” 步骤(确保常量池中有 “中国”);

2. 在堆内存中创建新的 String 对象,引用常量池中的 “中国”;

3. 变量s指向堆中的新对象。

六、与 StringBuffer 的对比

  • String:不可变,适合少量操作或共享场景。
  • StringBuffer:可变(底层数组无final修饰),适合频繁修改字符串的场景(如拼接、插入),且线程安全(方法被synchronized修饰)。