java基础:String字符串的用法详解
目录
- 一、String的本质
- 二、创建String的3种方式
- 三、核心方法详解
- 字符串比较
- 字符串查找
- 字符串操作
- 类型转换
- 四、性能优化技巧
- 五、String vs StringBuilder vs StringBuffer
- 六、字符串比较示例
- 七、底层原理进阶
String 是Java基础中非常重要的一个类,也是使用最频繁的类之一,它代表一个不可变的字符序列。以下是Java中
String类的用法详解:
一、String的本质
-
不可变性(Immutability)
- 字符串一旦创建,内容不可修改
- 所有修改操作(如
concat()/replace())都返回新对象
String s = "Hi"; s.concat(" Java"); // 返回新对象"Hi Java",原s仍为"Hi" -
存储机制
- 字符串常量池(String Pool):位于堆内存,避免重复创建
String s1 = "Fly"; // 存入常量池 String s2 = "Fly"; // 复用常量池对象(s1 == s2) String s3 = new String("Fly"); // 强制在堆中创建新对象(s1 != s3)
二、创建String的3种方式
| 方式 | 内存位置 | 是否复用常量池 |
|---|---|---|
String s = "abc"; | 常量池 | 是 |
new String("abc") | 堆内存 | 否(新对象) |
new String(char[]) | 堆内存 | 否 |
三、核心方法详解
字符串比较
// 1. 内容相等比较(重要!)
"java".equals("Java"); // false(区分大小写)
"java".equalsIgnoreCase("Java"); // true// 2. 字典序比较
"apple".compareTo("banana"); // 返回负数(a在b前)
"zoo".compareTo("apple"); // 返回正数// 3. 地址比较(慎用)
String s1 = new String("Hi");
String s2 = "Hi";
s1 == s2; // false(地址不同)
字符串查找
String text = "Java编程指南";// 1. 索引查找
text.indexOf("编程"); // 返回4(首次出现位置)
text.lastIndexOf('a'); // 返回3(最后出现位置)// 2. 前缀/后缀检查
text.startsWith("Java"); // true
text.endsWith("指南"); // true// 3. 包含判断
text.contains("编程"); // true
字符串操作
// 1. 截取子串
"HelloWorld".substring(5); // "World"(从索引5开始)
"HelloWorld".substring(0,5); // "Hello"([0,5)区间)// 2. 拼接(实际开发用"+"更常见)
String.join("-", "A","B","C"); // "A-B-C"// 3. 替换
"abac".replace('a', 'X'); // "XbXc"
"Java".replace("av", "**"); // "J**a"// 4. 大小写转换
"Java".toUpperCase(); // "JAVA"
"JAVA".toLowerCase(); // "java"// 5. 去除空白
" Hello ".trim(); // "Hello"(去首尾空格)
" Hi ".strip(); // "Hi"(JDK11+,支持全角空格)
类型转换
// 1. 其他类型 → String
String.valueOf(123); // "123"
String.valueOf(true); // "true"// 2. String → 数组
char[] chars = "Java".toCharArray(); // {'J','a','v','a'}
byte[] bytes = "Java".getBytes(); // UTF-8字节数组// 3. String → 数字
int num = Integer.parseInt("100"); // 100
double d = Double.parseDouble("3.14"); // 3.14
四、性能优化技巧
-
避免循环内拼接字符串
// 低效(每次循环创建新对象) String result = ""; for (int i=0; i<1000; i++) {result += i; }// 使用StringBuilder(减少对象创建) StringBuilder sb = new StringBuilder(); for (int i=0; i<1000; i++) {sb.append(i); } String result = sb.toString(); -
复用常量池对象
-
优先使用字面量赋值:
String s = "text"; -
调用
intern()方法主动入池:String s1 = new String("Hi").intern(); // 指向常量池对象 String s2 = "Hi"; s1 == s2; // true
-
五、String vs StringBuilder vs StringBuffer
| 特性 | String | StringBuilder | StringBuffer |
|---|---|---|---|
| 可变性 | 不可变 | 可变 | 可变 |
| 线程安全 | (天然安全) | (非线程安全) | (synchronized) |
| 性能 | 修改操作慢 | 修改操作快 | 修改操作中等 |
| 使用场景 | 常量字符串 | 单线程字符串操作 | 多线程字符串操作 |
六、字符串比较示例
String s1 = new String("Hi").intern(); // 指向常量池对象
String s2 = new String("Hi");
String s3 = "Hi";
System.out.println("s1 == s2 : " + (s1 == s2));
System.out.println("s1 == s3 : " + (s1 == s3));
System.out.println("s2 == s3 : " + (s2 == s3));
运行结果

intern()方法可以将内容放入常量池(如果池中没有),并返回池中对象的引用
s2是在堆中创建了一个新的String对象
s3指向常量池中的对象,固 s1==s3为true
七、底层原理进阶
- Java 9+的存储优化
- 旧版:
char[](每个字符2字节) - 新版:`byte[] +编码标记**(拉丁字符用1字节存储,节省内存)
- 旧版:
- 字符串常量池位置
- JDK7前:位于永久代(PermGen)
- JDK7+:移至堆内存(避免永久代溢出)
