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
相关推荐
Javatutouhouduan5 小时前
2026Java面试的正确打开方式!
java·高并发·java面试·java面试题·后端开发·java编程·java八股文
chao1898446 小时前
基于 SPEA2 的多目标优化算法 MATLAB 实现
开发语言·算法·matlab
JAVA面经实录9176 小时前
Java初级最终完整版学习路线图
java·spring·eclipse·maven
赏金术士6 小时前
Kotlin 习题集 · 高级篇
android·开发语言·kotlin
Cat_Rocky7 小时前
k8s-持久化存储,粗浅学习
java·学习·kubernetes
楼兰公子7 小时前
buildroot 在编译rust时裁剪平台类型数量的方法
开发语言·后端·rust
知识领航员7 小时前
蘑兔AI音乐深度实测:功能拆解、实测表现与适用场景
java·c语言·c++·人工智能·python·算法·github
吴声子夜歌7 小时前
Go——并发编程
开发语言·后端·golang
释怀°Believe8 小时前
Spring解析
java·后端·spring
ooseabiscuit8 小时前
Laravel4.x:现代PHP框架的奠基之作
java·开发语言·php