当前位置: 首页 > news >正文

Java中String类

Java中的String详解

1. String类核心概念

1.1 不可变性(Immutability)

String类是不可变的(Immutable),这是其最重要的特性:

public final class String implements Serializable, Comparable<String>, CharSequence {// 字符数组被final修饰,且没有提供修改方法private final char[] value;  // JDK 8// private final byte[] value; // JDK 9+
}

不可变性的实现原理:

  • String类被final修饰,不能被继承
  • 内部字符数组valuefinal修饰
  • 没有提供任何修改内部状态的方法
  • 所有"修改"操作都返回新的String对象

示例代码:

public class StringImmutableDemo {public static void main(String[] args) {String str1 = "Hello";String str2 = str1.concat(" World");System.out.println("str1: " + str1);        // 输出: HelloSystem.out.println("str2: " + str2);        // 输出: Hello WorldSystem.out.println("str1 == str2: " + (str1 == str2)); // false// str1的值没有改变,concat()返回了新的String对象}
}

1.2 不可变性的优势

  1. 线程安全:多线程环境下无需同步
  2. 缓存HashCode:String的hashCode只需计算一次
  3. 字符串常量池:相同内容的字符串可以共享内存
  4. 安全性:防止恶意修改,适合作为HashMap的key

2. String的内存模型

2.1 字符串存储位置

public class StringMemoryDemo {public static void main(String[] args) {// 1. 字符串字面量 - 存储在字符串常量池String str1 = "Hello";String str2 = "Hello";System.out.println(str1 == str2); // true - 指向同一个对象// 2. new关键字 - 在堆中创建新对象String str3 = new String("Hello");String str4 = new String("Hello");System.out.println(str3 == str4); // false - 不同对象System.out.println(str1 == str3); // false - 不同位置// 3. 内容比较System.out.println(str1.equals(str3)); // true - 内容相同}
}

2.2 JVM内存分布

JVM内存
方法区(元空间)
堆内存
栈内存
字符串常量池
'Hello' (str1, str2指向)
str1 (引用)
str2 (引用)
str3 (引用)
String对象1 (str3指向)
str4 (引用)
String对象2 (str4指向)
类信息、常量等
其他对象

3. String常用方法详解

3.1 字符串创建和基本操作

public class StringMethodsDemo {public static void main(String[] args) {String str = "Hello World Java";// 长度和判空System.out.println("长度: " + str.length());           // 16System.out.println("是否为空: " + str.isEmpty());       // falseSystem.out.println("是否为空白: " + str.isBlank());     // false (JDK 11+)// 字符访问System.out.println("第6个字符: " + str.charAt(5));      // 'W'System.out.println("字符数组: " + Arrays.toString(str.toCharArray()));// 子字符串System.out.println("子串(6,11): " + str.substring(6, 11)); // "World"System.out.println("从索引6开始: " + str.substring(6));      // "World Java"}
}

3.2 字符串查找和匹配

public class StringSearchDemo {public static void main(String[] args) {String text = "Java is great, Java is powerful";// 查找方法System.out.println("包含'great': " + text.contains("great"));        // trueSystem.out.println("以'Java'开头: " + text.startsWith("Java"));       // trueSystem.out.println("以'powerful'结尾: " + text.endsWith("powerful")); // true// 索引查找System.out.println("'Java'首次出现位置: " + text.indexOf("Java"));      // 0System.out.println("'Java'最后出现位置: " + text.lastIndexOf("Java"));  // 15System.out.println("从索引5开始查找'is': " + text.indexOf("is", 5));    // 5// 正则匹配System.out.println("匹配模式: " + text.matches(".*Java.*"));           // true}
}

3.3 字符串转换和处理

public class StringTransformDemo {public static void main(String[] args) {String original = "  Hello World Java  ";// 大小写转换System.out.println("大写: " + original.toUpperCase());System.out.println("小写: " + original.toLowerCase());// 去除空白System.out.println("去除首尾空白: '" + original.trim() + "'");System.out.println("去除所有空白: '" + original.strip() + "'"); // JDK 11+// 替换操作System.out.println("替换空格为'-': " + original.replace(" ", "-"));System.out.println("替换首个'l': " + original.replaceFirst("l", "L"));System.out.println("正则替换: " + original.replaceAll("\\s+", "_"));// 分割String[] words = original.trim().split("\\s+");System.out.println("分割结果: " + Arrays.toString(words));}
}

4. String、StringBuffer、StringBuilder对比

4.1 核心特性对比

特性StringStringBufferStringBuilder
可变性不可变可变可变
线程安全是(同步方法)
性能低(频繁操作时)中等
内存开销高(创建新对象)
适用场景少量字符串操作多线程环境单线程环境

4.2 详细特性分析

4.2.1 String类
public class StringAnalysis {public static void main(String[] args) {// String的不可变性导致每次操作都创建新对象String str = "Hello";str = str + " World";  // 创建新的String对象str = str + " Java";   // 再次创建新对象// 线程安全:由于不可变性,天然线程安全// 适用场景:字符串内容不频繁变化的情况}
}
4.2.2 StringBuffer类
public class StringBufferAnalysis {public static void main(String[] args) {// StringBuffer是可变的,线程安全StringBuffer sb = new StringBuffer("Hello");sb.append(" World");   // 在原对象上修改,不创建新对象sb.append(" Java");    // 继续在原对象上修改// 所有方法都是synchronized的// 适用场景:多线程环境下的字符串操作System.out.println(sb.toString());}
}
4.2.3 StringBuilder类
public class StringBuilderAnalysis {public static void main(String[] args) {// StringBuilder是可变的,非线程安全,性能最好StringBuilder sb = new StringBuilder("Hello");sb.append(" World");   // 在原对象上修改sb.append(" Java");    // 性能最优// 方法不是synchronized的,性能更好// 适用场景:单线程环境下的字符串操作System.out.println(sb.toString());}
}

4.3 使用场景总结

public class StringUsageScenarios {// 场景1:少量字符串操作 - 使用Stringpublic String formatUserInfo(String name, int age) {return "用户: " + name + ", 年龄: " + age;  // 简单拼接,使用String}// 场景2:多线程环境下的字符串构建 - 使用StringBufferpublic class LogBuffer {private StringBuffer buffer = new StringBuffer();public synchronized void addLog(String message) {buffer.append(System.currentTimeMillis()).append(": ").append(message).append("\n");}public synchronized String getLogs() {return buffer.toString();}}// 场景3:单线程环境下的大量字符串操作 - 使用StringBuilderpublic String generateReport(List<String> data) {StringBuilder report = new StringBuilder();report.append("=== 报告开始 ===\n");for (String item : data) {report.append("- ").append(item).append("\n");}report.append("=== 报告结束 ===");return report.toString();}
}

5. 字符串常量池与intern()方法

5.1 字符串常量池机制

字符串常量池(String Pool)是JVM为了优化字符串存储而设计的特殊内存区域:

public class StringPoolDemo {public static void main(String[] args) {// 字面量直接进入常量池String s1 = "hello";String s2 = "hello";System.out.println(s1 == s2);  // true - 指向同一个对象// new创建的对象在堆中String s3 = new String("hello");System.out.println(s1 == s3);  // false - 不同位置// 编译时常量拼接会进入常量池String s4 = "hel" + "lo";System.out.println(s1 == s4);  // true - 编译时优化// 运行时拼接不会进入常量池String prefix = "hel";String s5 = prefix + "lo";System.out.println(s1 == s5);  // false - 运行时创建}
}

5.2 intern()方法详解

intern()方法用于手动将字符串加入常量池:

public class InternMethodDemo {public static void main(String[] args) {// 基本用法String s1 = new String("hello");String s2 = s1.intern();  // 将s1的内容加入常量池String s3 = "hello";System.out.println(s1 == s2);  // false - s1在堆中,s2指向常量池System.out.println(s2 == s3);  // true - 都指向常量池// intern()的返回值String s4 = new String("world");String s5 = s4.intern();String s6 = s4.intern();System.out.println(s5 == s6);  // true - intern()返回常量池中的引用// 性能考虑demonstrateInternPerformance();}private static void demonstrateInternPerformance() {long startTime = System.currentTimeMillis();// 大量使用intern()可能导致性能问题for (int i = 0; i < 100000; i++) {String s = new String("test" + i).intern();}long endTime = System.currentTimeMillis();System.out.println("intern()操作耗时: " + (endTime - startTime) + "ms");}
}

5.3 JDK版本差异

public class InternVersionDifference {public static void main(String[] args) {// JDK 6 vs JDK 7+ 的区别String s1 = new String("1") + new String("1");String s2 = s1.intern();String s3 = "11";// JDK 6: s1 != s2, s2 == s3// JDK 7+: s1 == s2, s2 == s3System.out.println("s1 == s2: " + (s1 == s2));System.out.println("s2 == s3: " + (s2 == s3));/** JDK 6: 常量池在永久代,intern()会复制对象到常量池* JDK 7+: 常量池在堆中,intern()可能只存储引用*/}
}

6. 性能优化最佳实践

6.1 避免在循环中进行字符串拼接

public class StringOptimization {// ❌ 错误做法:在循环中使用String拼接public String badConcatenation(List<String> items) {String result = "";for (String item : items) {result += item + ",";  // 每次都创建新对象}return result;}// ✅ 正确做法:使用StringBuilderpublic String goodConcatenation(List<String> items) {StringBuilder sb = new StringBuilder();for (String item : items) {sb.append(item).append(",");}return sb.toString();}// ✅ 更好的做法:使用String.join() (JDK 8+)public String bestConcatenation(List<String> items) {return String.join(",", items);}
}

6.2 合理使用StringBuilder的容量

public class StringBuilderOptimization {// ❌ 未指定初始容量,可能频繁扩容public String inefficientBuilder(List<String> items) {StringBuilder sb = new StringBuilder();  // 默认容量16for (String item : items) {sb.append(item);}return sb.toString();}// ✅ 预估容量,减少扩容次数public String efficientBuilder(List<String> items) {int estimatedLength = items.size() * 10;  // 预估总长度StringBuilder sb = new StringBuilder(estimatedLength);for (String item : items) {sb.append(item);}return sb.toString();}
}

6.3 字符串比较优化

public class StringComparisonOptimization {// ✅ 使用equals()进行内容比较public boolean safeEquals(String s1, String s2) {return Objects.equals(s1, s2);  // 处理null情况}// ✅ 常量放在前面,避免NullPointerExceptionpublic boolean constantFirst(String input) {return "ADMIN".equals(input);  // 而不是 input.equals("ADMIN")}// ✅ 使用equalsIgnoreCase()进行忽略大小写比较public boolean caseInsensitiveEquals(String s1, String s2) {return s1 != null && s1.equalsIgnoreCase(s2);}
}

6.4 JDK 8+ 字符串优化特性

public class ModernStringOptimization {// JDK 8: 编译器自动优化字符串拼接public String compilerOptimization() {String name = "张三";int age = 25;// 编译器会自动转换为StringBuilder操作return "姓名: " + name + ", 年龄: " + age;}// JDK 8+: 使用String.join()public String joinStrings(String... parts) {return String.join(" - ", parts);}// JDK 11+: 使用新的字符串方法public void modernStringMethods() {String text = "  Hello World  ";// 重复字符串String repeated = "=".repeat(10);  // "=========="// 判断空白boolean isBlank = text.isBlank();// 去除空白(比trim()更强大)String stripped = text.strip();// 按行分割text.lines().forEach(System.out::println);}
}
http://www.dtcms.com/a/513224.html

相关文章:

  • 呼伦贝尔网站制作网站续费能自己续费吗
  • 怎么去掉wordpress加载动画南京做网站优化
  • Godot4.x的整体架构图解析-源码阅读
  • 广州短视频网站开发服装网站设计
  • 网站自动弹窗代码郑州做网页的公司
  • 做膜结构那个网站好网站切换
  • 怎么用自助网站宁波seo怎么推广
  • 网站排名alexa常用网站有哪些
  • 【DeepSeek新开源】DeepSeek-OCR如何用“视觉压缩”革新长文本处理
  • 反向代理应用:frp
  • SetConsoleCursorPosition函数的用法
  • 一个服务器可以放多少个网站个性化网站建设开发
  • 赣州建站服务山东省工程造价信息网官网
  • 重庆定制网站建设写一个app多少钱
  • 如何做公司宣传网站简单网页制作教程视频
  • @JvmStatic 的作用
  • 单位门户网站功能免费做网站怎么做网站
  • 黄石网站建设定做网站建设公司专业网站科技开发
  • FreeRTOS任务状态获取
  • 南城网站优化公司查询网站流量排名
  • 网站注册可以免费吗开发工具箱
  • 寮步镇网站建设网站版面设计流程包括哪些
  • 做海报用什么网站网络公司给销售公司做网站
  • EPLAN 保姆级入门教学
  • 动态规划经典问题学习笔记
  • java重构旧代码有哪些注意的点
  • 湛江廉江网站建设WordPress留言表单仿制
  • 如何优化一个网站案例网站模板_案例网
  • 青岛开发网站深圳福田区房子价格
  • JeecgBoot积木报表综合漏洞检测工具