1. String基础概念解析
在编程世界里,String(字符串)就像现实生活中的语言交流一样无处不在。无论是用户输入的账号密码、网页显示的文本内容,还是API接口传输的数据,本质上都是由字符组成的序列。Java中的String类位于java.lang包下,是一个final类,这意味着它不能被继承,也保证了字符串操作的安全性。
String的内部实现其实是一个char数组(JDK9后改为byte数组配合编码标记),这个设计决定了它的两大特性:不可变性和字符串常量池机制。每次看似"修改"字符串的操作,实际上都是创建了新的String对象。比如执行str += "append"时,JVM会先创建一个StringBuilder对象,完成拼接后再生成新的String实例。
重要提示:在循环体内进行字符串拼接时,务必使用StringBuilder而非直接"+"操作,否则会产生大量临时对象影响性能
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 字符串创建与初始化
2.1 直接赋值与构造器区别
java复制String s1 = "hello"; // 方式一:字面量赋值
String s2 = new String("hello"); // 方式二:构造器创建
这两种创建方式在内存分配上有本质区别:
- 字面量方式会先检查字符串常量池,若存在则直接引用,否则在池中创建对象
- new操作会强制在堆内存新建对象,即使常量池已有相同内容
验证代码:
java复制System.out.println(s1 == s2); // false,地址不同
System.out.println(s1.equals(s2)); // true,内容相同
2.2 字符串常量池优化
JVM对字符串有特殊优化机制:
- 编译期优化:多个字面量连接会被合并
java复制String s3 = "he" + "llo"; // 编译后等同于"hello" System.out.println(s1 == s3); // true - intern()方法手动入池
java复制String s4 = new String("world").intern(); String s5 = "world"; System.out.println(s4 == s5); // true
3. 字符串常用操作大全
3.1 基础查询方法
| 方法签名 | 功能说明 | 示例 |
|---|---|---|
| length() | 返回字符串长度 | "abc".length() → 3 |
| charAt(int) | 获取指定位置字符 | "java".charAt(2) → 'v' |
| indexOf(String) | 查找子串位置 | "hello".indexOf("ll") → 2 |
| isEmpty() | 判断是否空串 | "".isEmpty() → true |
3.2 字符串比较操作
java复制// 区分大小写比较
"Java".equals("java"); // false
// 忽略大小写比较
"Java".equalsIgnoreCase("java"); // true
// 字典序比较
"apple".compareTo("banana"); // 负数(a在b前)
实际开发中推荐使用Objects.equals()进行null安全比较
3.3 字符串截取与分割
java复制// 子串截取
String url = "https://example.com";
String domain = url.substring(8); // "example.com"
String proto = url.substring(0,5); // "https"
// 正则分割
String csv = "a,b,c,d";
String[] arr = csv.split(","); // ["a","b","c","d"]
// 多分隔符场景
String log = "2023-08-01 12:30:45 [INFO]";
String[] parts = log.split("\\s+|\\[|\\]");
// ["2023-08-01","12:30:45","INFO"]
3.4 字符串格式化
java复制// 传统占位符
String msg = String.format("欢迎%s,当前积分:%d", "张三", 1500);
// 新式模板字符串(Java15+)
String json = `
{
"name": "%s",
"age": %d
}`.formatted("李四", 28);
4. 字符串高级处理技巧
4.1 正则表达式应用
java复制// 邮箱验证
boolean isValidEmail = "user@example.com".matches("\\w+@\\w+\\.\\w+");
// 提取数字
String text = "订单号:ORD202308011234";
Pattern p = Pattern.compile("\\d+");
Matcher m = p.matcher(text);
if(m.find()) {
String orderNum = m.group(); // "202308011234"
}
4.2 编码转换处理
java复制// 乱码修复常见场景
String gbkStr = new String(byteData, "GBK");
String utf8Str = new String(gbkStr.getBytes("GBK"), "UTF-8");
// Base64编解码
String encoded = Base64.getEncoder().encodeToString("data".getBytes());
String decoded = new String(Base64.getDecoder().decode(encoded));
4.3 性能优化实践
-
拼接优化对比
java复制// 反例(产生多个临时对象) String result = ""; for(int i=0; i<100; i++) { result += i; } // 正例 StringBuilder sb = new StringBuilder(); for(int i=0; i<100; i++) { sb.append(i); } String optimized = sb.toString(); -
StringJoiner使用
java复制StringJoiner sj = new StringJoiner(", ", "[", "]"); sj.add("Java").add("Python").add("Go"); System.out.println(sj); // [Java, Python, Go]
5. 常见问题排查指南
5.1 内存泄漏场景
java复制// 大字符串substring导致
