Java String 类详解:字符串常用方法 + 不可变性 一网打尽

引入

我们之前学过:Java 里 everything is object,所有类都属于某个包。同一个项目里可能出现同名类,为了不混淆,就要用 全类名(包名 + 类名) 来唯一确定一个类。

之前我们写过:

复制代码
public class Student { ... }

这个 Student 就是一个类,我们可以创建对象:

复制代码
Student stu = new Student();

而**String 也是一个类** ,和 Student 本质一样,只是它是 Java 官方提前写好的类。

它所在的包是 java.lang,所以它的全类名就是:

复制代码
java.lang.String

就像我们用 Scanner 要写 java.util.Scanner 一样,String 也有自己完整的 "全名",只是因为 java.lang 包默认自动导入 ,我们平时可以直接简写为 String。

简单总结一句String 就是一个和我们自己写的 Student 一样的引用类型类,只是它是系统自带的,全名是 java.lang.String。


1. String 常用方法

1.1 字符串三种构造方式

String 提供了非常多的构造方式,最常用的就 3 种:

复制代码
public static void main(String[] args) {
    // 1. 使用常量串构造(最常用)
    String s1 = "hello bit";
    System.out.println(s1);

    // 2. 直接 new String 对象
    String s2 = new String("hello bit");
    System.out.println(s2);

    // 3. 使用字符数组构造
    char[] array = {'h','e','l','l','o','b','i','t'};
    String s3 = new String(array);
    System.out.println(s3);
}

1.2 String 对象的四种比较方式

1)== 比较:比地址

  1. 基本类型:== 比

  2. 引用类型:== 比地址

    public static void main(String[] args) {
    String s1 = new String("hello");
    String s2 = new String("hello");
    String s3 = s1;

    复制代码
     System.out.println(s1 == s2);   // false(地址不同)
     System.out.println(s1 == s3);   // true(地址相同)

    }


2)equals ():比内容(最常用)

String 重写了 Objectequals()按字符逐个比较内容

复制代码
public static void main(String[] args) {
    String s1 = new String("hello");
    String s2 = new String("hello");
    String s3 = new String("Hello");

    System.out.println(s1.equals(s2));  // true
    System.out.println(s1.equals(s3));  // false
}

3)compareTo ():按字典序比大小(返回 int)

复制代码
public static void main(String[] args) {
    String s1 = "abc";
    String s2 = "ac";
    String s3 = "abcdef";

    System.out.println(s1.compareTo(s2));   // -1
    System.out.println(s1.compareTo(s3));   // -3
}

4)compareToIgnoreCase ():忽略大小写比较

复制代码
String s1 = "abc";
String s2 = "ABC";
System.out.println(s1.compareToIgnoreCase(s2)); // 0

1.3 字符串查找(超常用)

复制代码
public static void main(String[] args) {
    String s = "aaabbbcccaaabbbccc";

    System.out.println(s.charAt(3));        // 'b'
    System.out.println(s.indexOf('c'));     // 6
    System.out.println(s.indexOf("bbb"));   // 3
    System.out.println(s.lastIndexOf('c')); // 17
}

1.4 类型转换(开发必备)

1)数字 / 布尔 → 字符串

复制代码
String s1 = String.valueOf(123);
String s2 = String.valueOf(12.34);
String s3 = String.valueOf(true);

2)字符串 → 数字

复制代码
int a = Integer.parseInt("1234");
double d = Double.parseDouble("12.99");

3)大小写转换

复制代码
String s = "Hello";
System.out.println(s.toUpperCase()); // HELLO
System.out.println(s.toLowerCase()); // hello

4)字符串 ↔ 字符数组

复制代码
String s = "hello";
char[] ch = s.toCharArray(); // 转数组
String s2 = new String(ch);  // 转回字符串

5)格式化字符串

复制代码
String s = String.format("%d-%02d-%02d", 2025, 4, 2);
System.out.println(s); // 2025-04-02

1.5 字符串替换(创建新对象!)

String 替换不会改原串 ,只会返回新字符串

复制代码
String str = "helloworld";
System.out.println(str.replaceAll("l", "_"));   // he__owor_d
System.out.println(str.replaceFirst("l", "_")); // he_loworld

1.6 字符串拆分(高频坑点)

普通拆分

复制代码
String str = "hello world hello bit";
String[] arr = str.split(" ");

特殊字符必须转义

. * + | \ 都要加 \

复制代码
String ip = "192.168.1.1";
String[] arr = ip.split("\\.");

1.7 字符串截取(左闭右开!)

复制代码
String str = "helloworld";
System.out.println(str.substring(5));      // world
System.out.println(str.substring(0,5));    // hello

✅ 重点:包含开头,不包含结尾


1.8 trim ():去掉首尾空白

复制代码
String str = "   hello world  ";
System.out.println(str.trim()); // hello world

2. String 不可变性(面试必考!)

2.1 什么是不可变?

String 对象一旦创建,内容永远不能改!所有 "修改" 操作(replace、trim、substring...)都会创建新字符串


2.2 不可变的真正原因

  1. String 类被 final 修饰,不能被继承
  2. 底层 value 数组被 private final 修饰
  3. 没有对外提供任何修改数组的方法

❌ 错误:final 让数组内容不能改

✅ 正确:final 只让引用不能改;真正不可变是封装 + 不提供修改方法


2.3 为什么 String 要设计成不可变?

  1. 实现字符串常量池,节省内存
  2. 线程安全,不用加锁
  3. 哈希码稳定,适合做 HashMap key
  4. 更安全(密码、路径不能被篡改)

2.4 想频繁修改字符串用什么?

  • StringBuilder:单线程最快

  • StringBuffer:线程安全(慢)

    StringBuilder sb = new StringBuilder();
    sb.append("hello").append(" world");


3. 我给你额外补充的干货

🔥 高频题:

1. ==equals 的区别?

  1. ==:基本类型比 ,引用类型比地址
  2. equals:默认比地址,String 重写后比内容

2. 下面代码创建几个对象?

复制代码
String s = new String("abc");

答案:1 个或 2 个

常量池没有 "abc" → 创建 2 个

常量池已有 "abc" → 创建 1 个

3. String 为什么不可变?

类 + 数组 private + 无修改方法 + final 保障


4. 终极总结

  1. String 是引用类型,全类名 java.lang.String
  2. 比较内容用 equals (),别用 ==
  3. 常用方法:
    • charAt
    • indexOf
    • split
    • substring
    • trim
    • replace
  4. String 不可变,所有修改都创建新对象
  5. 频繁修改用 StringBuilder
相关推荐
yaaakaaang2 小时前
四、建造者模式
java·建造者模式
顶点多余2 小时前
死锁+线程安全
linux·开发语言·c++·系统安全
2501_921649492 小时前
从WebSocket到SQL查询:金融数据落库存储及查询接口全流程开发
java·sql·websocket·程序人生·spring cloud·金融·系统架构
专注API从业者2 小时前
淘宝 API 调用链路追踪实战:基于 SkyWalking/Pinpoint 的全链路监控搭建
大数据·开发语言·数据库·skywalking
jinanwuhuaguo2 小时前
OpenClaw v2026.4.1 深度剖析报告:任务系统、协作生态与安全范式的全面跃迁
java·大数据·开发语言·人工智能·深度学习
努力不熬夜 ^_^2 小时前
我用 GLM-5.1 重构了我的 AI 项目
java·重构·react·glm·vibe coding·coding plan
小雷君2 小时前
SpringBoot + SpringSecurity + JWT 完整整合实战(生产级无状态认证)
java·spring boot·spring
澄风2 小时前
IDEA 代码模板配置教程(prs快捷生成private String)
java·ide·intellij-idea
弹简特2 小时前
【JavaEE25-后端部分】从“统一回执单”到“统一投诉处理”:Spring Boot 轻松搞定统一返回格式和统一异常处理
java·spring boot·后端·统一返回格式·统一异常